1 ;; Copyright (C) 2006-2018 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")
104 (define_c_enum "unspec" [
146 UNSPEC_SPU_REALIGN_LOAD
147 UNSPEC_SPU_MASK_FOR_LOAD
150 UNSPEC_FLOAT_TRUNCATE
155 (define_c_enum "unspecv" [
162 (include "predicates.md")
163 (include "constraints.md")
168 (define_mode_iterator ALL [QI V16QI
176 ; Everything except DI and TI which are handled separately because
177 ; they need different constraints to correctly test VOIDmode constants
178 (define_mode_iterator MOV [QI V16QI
185 (define_mode_iterator QHSI [QI HI SI])
186 (define_mode_iterator QHSDI [QI HI SI DI])
187 (define_mode_iterator DTI [DI TI])
189 (define_mode_iterator VINT [QI V16QI
195 (define_mode_iterator VQHSI [QI V16QI
199 (define_mode_iterator VHSI [HI V8HI
202 (define_mode_iterator VSDF [SF V4SF
205 (define_mode_iterator VSI [SI V4SI])
206 (define_mode_iterator VDI [DI V2DI])
207 (define_mode_iterator VSF [SF V4SF])
208 (define_mode_iterator VDF [DF V2DF])
210 (define_mode_iterator VCMP [V16QI
216 (define_mode_iterator VCMPU [V16QI
220 (define_mode_attr v [(V8HI "v") (V4SI "v")
223 (define_mode_attr bh [(QI "b") (V16QI "b")
227 (define_mode_attr d [(SF "") (V4SF "")
228 (DF "d") (V2DF "d")])
229 (define_mode_attr d6 [(SF "6") (V4SF "6")
230 (DF "d") (V2DF "d")])
232 (define_mode_attr f2i [(SF "si") (V4SF "v4si")
233 (DF "di") (V2DF "v2di")])
234 (define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
235 (DF "DI") (V2DF "V2DI")])
236 (define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
237 (DI "df") (V2DI "v2df")])
238 (define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
239 (DI "DF") (V2DI "V2DF")])
241 (define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
243 (define_mode_attr umask [(HI "f") (V8HI "f")
244 (SI "g") (V4SI "g")])
245 (define_mode_attr nmask [(HI "F") (V8HI "F")
246 (SI "G") (V4SI "G")])
248 ;; Used for carry and borrow instructions.
249 (define_mode_iterator CBOP [SI DI V4SI V2DI])
251 ;; Used in vec_set and vec_extract
252 (define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
253 (define_mode_attr inner [(V16QI "QI")
259 ;; Like above, but in lower case
260 (define_mode_attr inner_l [(V16QI "qi")
266 (define_mode_attr vmult [(V16QI "1")
272 (define_mode_attr voff [(V16QI "13")
282 (define_expand "mov<mode>"
283 [(set (match_operand:ALL 0 "nonimmediate_operand" "")
284 (match_operand:ALL 1 "general_operand" ""))]
287 if (spu_expand_mov(operands, <MODE>mode))
292 [(set (match_operand 0 "spu_reg_operand")
293 (match_operand 1 "immediate_operand"))]
297 (high (match_dup 1)))
299 (lo_sum (match_dup 0)
302 if (spu_split_immediate (operands))
308 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
309 (match_operand:SI 1 "immediate_operand" "s"))
314 ;; Whenever a function generates the 'pic' pattern above we need to
315 ;; load the pic_offset_table register.
316 ;; GCC doesn't deal well with labels in the middle of a block so we
317 ;; hardcode the offsets in the asm here.
318 (define_insn "load_pic_offset"
319 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
320 (unspec:SI [(const_int 0)] 0))
321 (set (match_operand:SI 1 "spu_reg_operand" "=r")
322 (unspec:SI [(const_int 0)] 0))]
324 "ila\t%1,.+8\;brsl\t%0,4"
325 [(set_attr "length" "8")
326 (set_attr "type" "multi0")])
331 (define_insn "_mov<mode>"
332 [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
333 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
334 "register_operand(operands[0], <MODE>mode)
335 || register_operand(operands[1], <MODE>mode)"
343 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
345 (define_insn "low_<mode>"
346 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
347 (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
348 (match_operand:VSI 2 "immediate_operand" "i")))]
352 (define_insn "_movdi"
353 [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
354 (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
355 "register_operand(operands[0], DImode)
356 || register_operand(operands[1], DImode)"
364 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
366 (define_insn "_movti"
367 [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
368 (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
369 "register_operand(operands[0], TImode)
370 || register_operand(operands[1], TImode)"
378 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
381 [(set (match_operand 0 "spu_reg_operand")
382 (match_operand 1 "memory_operand"))]
383 "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
384 && GET_MODE(operands[0]) == GET_MODE(operands[1])
385 && !reload_in_progress && !reload_completed"
388 { if (spu_split_load(operands))
393 [(set (match_operand 0 "memory_operand")
394 (match_operand 1 "spu_reg_operand"))]
395 "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
396 && GET_MODE(operands[0]) == GET_MODE(operands[1])
397 && !reload_in_progress && !reload_completed"
400 { if (spu_split_store(operands))
403 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
405 (define_expand "cpat"
406 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
407 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
408 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
409 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
412 rtx x = gen_cpat_const (operands);
415 emit_move_insn (operands[0], x);
421 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
422 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
423 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
424 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
429 [(set_attr "type" "shuf")])
432 [(set (match_operand:TI 0 "spu_reg_operand")
433 (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
434 (match_operand:SI 2 "immediate_operand")
435 (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
437 [(set (match_dup:TI 0)
440 operands[4] = gen_cpat_const (operands);
447 (define_insn "extendqihi2"
448 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
449 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
453 (define_insn "extendhisi2"
454 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
455 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
459 (define_expand "extendsidi2"
460 [(set (match_dup:DI 2)
461 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
462 (set (match_operand:DI 0 "spu_reg_operand" "")
463 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
464 (parallel [(const_int 1)]))))]
467 operands[2] = gen_reg_rtx (DImode);
468 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
472 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
475 (match_operand:V2SI 1 "spu_reg_operand" "r")
476 (parallel [(const_int 1) ]))))]
480 ;; By splitting this late we don't allow much opportunity for sharing of
481 ;; constants. That's ok because this should really be optimized away.
482 (define_insn_and_split "extend<mode>ti2"
483 [(set (match_operand:TI 0 "register_operand" "")
484 (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
488 [(set (match_dup:TI 0)
489 (sign_extend:TI (match_dup:QHSDI 1)))]
491 spu_expand_sign_extend(operands);
498 (define_insn "zero_extendqihi2"
499 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
500 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
502 "andi\t%0,%1,0x00ff")
504 (define_insn "zero_extendqisi2"
505 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
506 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
508 "andi\t%0,%1,0x00ff")
510 (define_expand "zero_extendhisi2"
511 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
512 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
513 (clobber (match_scratch:SI 2 "=&r"))]
516 rtx mask = gen_reg_rtx (SImode);
517 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
518 emit_move_insn (mask, GEN_INT (0xffff));
519 emit_insn (gen_andsi3(operands[0], op1, mask));
523 (define_insn "zero_extendsidi2"
524 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
525 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
528 [(set_attr "type" "shuf")])
530 (define_insn "zero_extendqiti2"
531 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
532 (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
534 "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
535 [(set_attr "type" "multi0")
536 (set_attr "length" "8")])
538 (define_insn "zero_extendhiti2"
539 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
540 (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
542 "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
543 [(set_attr "type" "multi1")
544 (set_attr "length" "8")])
546 (define_insn "zero_extendsiti2"
547 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
548 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
550 "rotqmbyi\t%0,%1,-12"
551 [(set_attr "type" "shuf")])
553 (define_insn "zero_extendditi2"
554 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
555 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
558 [(set_attr "type" "shuf")])
563 (define_insn "truncdiqi2"
564 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
565 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
568 [(set_attr "type" "shuf")])
570 (define_insn "truncdihi2"
571 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
572 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
575 [(set_attr "type" "shuf")])
577 (define_insn "truncdisi2"
578 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
579 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
582 [(set_attr "type" "shuf")])
584 (define_insn "trunctiqi2"
585 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
586 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
589 [(set_attr "type" "shuf")])
591 (define_insn "trunctihi2"
592 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
593 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
596 [(set_attr "type" "shuf")])
598 (define_insn "trunctisi2"
599 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
600 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
603 [(set_attr "type" "shuf")])
605 (define_insn "trunctidi2"
606 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
607 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
610 [(set_attr "type" "shuf")])
615 (define_insn "float<mode><i2f>2"
616 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
617 (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
620 [(set_attr "type" "fp7")])
622 (define_insn "fix_trunc<mode><f2i>2"
623 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
624 (fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
627 [(set_attr "type" "fp7")])
629 (define_insn "floatuns<mode><i2f>2"
630 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
631 (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
634 [(set_attr "type" "fp7")])
636 (define_insn "fixuns_trunc<mode><f2i>2"
637 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
638 (unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
641 [(set_attr "type" "fp7")])
643 (define_insn "float<mode><i2f>2_mul"
644 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
645 (mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
646 (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
649 [(set_attr "type" "fp7")])
651 (define_insn "float<mode><i2f>2_div"
652 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
653 (div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
654 (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
657 [(set_attr "type" "fp7")])
660 (define_insn "fix_trunc<mode><f2i>2_mul"
661 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
662 (fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
663 (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
666 [(set_attr "type" "fp7")])
668 (define_insn "floatuns<mode><i2f>2_mul"
669 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
670 (mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
671 (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
674 [(set_attr "type" "fp7")])
676 (define_insn "floatuns<mode><i2f>2_div"
677 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
678 (div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
679 (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
682 [(set_attr "type" "fp7")])
684 (define_insn "fixuns_trunc<mode><f2i>2_mul"
685 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
686 (unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
687 (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
690 [(set_attr "type" "fp7")])
692 (define_insn "extendsfdf2"
693 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
694 (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
695 UNSPEC_FLOAT_EXTEND))]
698 [(set_attr "type" "fpd")])
700 (define_insn "truncdfsf2"
701 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
702 (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
703 UNSPEC_FLOAT_TRUNCATE))]
706 [(set_attr "type" "fpd")])
708 (define_expand "floatdisf2"
709 [(set (match_operand:SF 0 "register_operand" "")
710 (float:SF (match_operand:DI 1 "register_operand" "")))]
713 rtx c0 = gen_reg_rtx (SImode);
714 rtx r0 = gen_reg_rtx (DImode);
715 rtx r1 = gen_reg_rtx (SFmode);
716 rtx r2 = gen_reg_rtx (SImode);
717 rtx setneg = gen_reg_rtx (SImode);
718 rtx isneg = gen_reg_rtx (SImode);
719 rtx neg = gen_reg_rtx (DImode);
720 rtx mask = gen_reg_rtx (DImode);
722 emit_move_insn (c0, GEN_INT (-0x80000000ll));
724 emit_insn (gen_negdi2 (neg, operands[1]));
725 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
726 emit_insn (gen_extend_compare (mask, isneg));
727 emit_insn (gen_selb (r0, neg, operands[1], mask));
728 emit_insn (gen_andc_si (setneg, c0, isneg));
730 emit_insn (gen_floatunsdisf2 (r1, r0));
732 emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
733 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
737 (define_insn_and_split "floatunsdisf2"
738 [(set (match_operand:SF 0 "register_operand" "=r")
739 (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))
740 (clobber (match_scratch:SF 2 "=r"))
741 (clobber (match_scratch:SF 3 "=r"))
742 (clobber (match_scratch:SF 4 "=r"))]
746 [(set (match_dup:SF 0)
747 (unsigned_float:SF (match_dup:DI 1)))]
749 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
750 rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
751 rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
752 rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
754 REAL_VALUE_TYPE scale;
755 real_2expN (&scale, 32, SFmode);
757 emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
758 emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
760 emit_move_insn (operands[4],
761 const_double_from_real_value (scale, SFmode));
762 emit_insn (gen_fmasf4 (operands[0],
763 operands[2], operands[4], operands[3]));
767 (define_expand "floattisf2"
768 [(set (match_operand:SF 0 "register_operand" "")
769 (float:SF (match_operand:TI 1 "register_operand" "")))]
772 rtx c0 = gen_reg_rtx (SImode);
773 rtx r0 = gen_reg_rtx (TImode);
774 rtx r1 = gen_reg_rtx (SFmode);
775 rtx r2 = gen_reg_rtx (SImode);
776 rtx setneg = gen_reg_rtx (SImode);
777 rtx isneg = gen_reg_rtx (SImode);
778 rtx neg = gen_reg_rtx (TImode);
779 rtx mask = gen_reg_rtx (TImode);
781 emit_move_insn (c0, GEN_INT (-0x80000000ll));
783 emit_insn (gen_negti2 (neg, operands[1]));
784 emit_insn (gen_cgt_ti_m1 (isneg, operands[1]));
785 emit_insn (gen_extend_compare (mask, isneg));
786 emit_insn (gen_selb (r0, neg, operands[1], mask));
787 emit_insn (gen_andc_si (setneg, c0, isneg));
789 emit_insn (gen_floatunstisf2 (r1, r0));
791 emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
792 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
796 (define_insn_and_split "floatunstisf2"
797 [(set (match_operand:SF 0 "register_operand" "=r")
798 (unsigned_float:SF (match_operand:TI 1 "register_operand" "r")))
799 (clobber (match_scratch:SF 2 "=r"))
800 (clobber (match_scratch:SF 3 "=r"))
801 (clobber (match_scratch:SF 4 "=r"))]
805 [(set (match_dup:SF 0)
806 (unsigned_float:SF (match_dup:TI 1)))]
808 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
809 rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
810 rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
811 rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
813 REAL_VALUE_TYPE scale;
814 real_2expN (&scale, 32, SFmode);
816 emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
817 emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
819 emit_move_insn (operands[4],
820 const_double_from_real_value (scale, SFmode));
821 emit_insn (gen_fmasf4 (operands[2],
822 operands[2], operands[4], operands[3]));
824 emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
825 emit_insn (gen_fmasf4 (operands[2],
826 operands[2], operands[4], operands[3]));
828 emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
829 emit_insn (gen_fmasf4 (operands[0],
830 operands[2], operands[4], operands[3]));
834 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
835 (define_expand "floatsidf2"
836 [(set (match_operand:DF 0 "register_operand" "")
837 (float:DF (match_operand:SI 1 "register_operand" "")))]
840 rtx c0 = gen_reg_rtx (SImode);
841 rtx c1 = gen_reg_rtx (DFmode);
842 rtx r0 = gen_reg_rtx (SImode);
843 rtx r1 = gen_reg_rtx (DFmode);
845 emit_move_insn (c0, GEN_INT (-0x80000000ll));
846 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
847 emit_insn (gen_xorsi3 (r0, operands[1], c0));
848 emit_insn (gen_floatunssidf2 (r1, r0));
849 emit_insn (gen_subdf3 (operands[0], r1, c1));
853 (define_expand "floatunssidf2"
854 [(set (match_operand:DF 0 "register_operand" "=r")
855 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
859 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
860 0x06071415, 0x16178080);
861 rtx r0 = gen_reg_rtx (V16QImode);
867 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
869 NULL_RTX, LCT_NORMAL, DFmode,
870 operands[1], SImode);
871 rtx_insn *insns = get_insns ();
873 emit_libcall_block (insns, operands[0], value,
874 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
878 emit_move_insn (r0, c0);
879 emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
884 (define_insn_and_split "floatunssidf2_internal"
885 [(set (match_operand:DF 0 "register_operand" "=r")
886 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))
887 (use (match_operand:V16QI 2 "register_operand" "r"))
888 (clobber (match_scratch:V4SI 3 "=&r"))
889 (clobber (match_scratch:V4SI 4 "=&r"))
890 (clobber (match_scratch:V4SI 5 "=&r"))
891 (clobber (match_scratch:V4SI 6 "=&r"))]
893 "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"
895 [(set (match_dup:DF 0)
896 (unsigned_float:DF (match_dup:SI 1)))]
899 rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
900 rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
901 rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
902 rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
903 emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
904 emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
905 emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
906 emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
907 emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
908 emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
909 emit_insn (gen_andc_v4si (ops[6],ops[6],ops[5]));
910 emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
911 emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
914 [(set_attr "length" "32")])
916 (define_expand "floatdidf2"
917 [(set (match_operand:DF 0 "register_operand" "")
918 (float:DF (match_operand:DI 1 "register_operand" "")))]
921 rtx c0 = gen_reg_rtx (DImode);
922 rtx r0 = gen_reg_rtx (DImode);
923 rtx r1 = gen_reg_rtx (DFmode);
924 rtx r2 = gen_reg_rtx (DImode);
925 rtx setneg = gen_reg_rtx (DImode);
926 rtx isneg = gen_reg_rtx (SImode);
927 rtx neg = gen_reg_rtx (DImode);
928 rtx mask = gen_reg_rtx (DImode);
930 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
932 emit_insn (gen_negdi2 (neg, operands[1]));
933 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
934 emit_insn (gen_extend_compare (mask, isneg));
935 emit_insn (gen_selb (r0, neg, operands[1], mask));
936 emit_insn (gen_andc_di (setneg, c0, mask));
938 emit_insn (gen_floatunsdidf2 (r1, r0));
940 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
941 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
945 (define_expand "floatunsdidf2"
946 [(set (match_operand:DF 0 "register_operand" "=r")
947 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
951 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
952 0x06071415, 0x16178080);
953 rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
954 rtx r0 = gen_reg_rtx (V16QImode);
955 rtx r1 = gen_reg_rtx (V4SImode);
961 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
963 NULL_RTX, LCT_NORMAL, DFmode,
964 operands[1], DImode);
965 rtx_insn *insns = get_insns ();
967 emit_libcall_block (insns, operands[0], value,
968 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
972 emit_move_insn (r1, c1);
973 emit_move_insn (r0, c0);
974 emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
979 (define_insn_and_split "floatunsdidf2_internal"
980 [(set (match_operand:DF 0 "register_operand" "=r")
981 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))
982 (use (match_operand:V16QI 2 "register_operand" "r"))
983 (use (match_operand:V4SI 3 "register_operand" "r"))
984 (clobber (match_scratch:V4SI 4 "=&r"))
985 (clobber (match_scratch:V4SI 5 "=&r"))
986 (clobber (match_scratch:V4SI 6 "=&r"))]
988 "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"
990 [(set (match_operand:DF 0 "register_operand" "=r")
991 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
994 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
995 rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
996 rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
997 rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
998 rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
999 rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
1000 emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
1001 emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
1002 emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
1003 emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
1004 emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
1005 emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
1006 emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
1007 emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
1008 emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
1009 emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
1012 [(set_attr "length" "40")])
1017 (define_expand "addv16qi3"
1018 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1019 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1020 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1023 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1024 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1025 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1026 rtx rhs_and = gen_reg_rtx (V8HImode);
1027 rtx hi_char = gen_reg_rtx (V8HImode);
1028 rtx lo_char = gen_reg_rtx (V8HImode);
1029 rtx mask = gen_reg_rtx (V8HImode);
1031 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1032 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1033 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
1034 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
1035 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1039 (define_insn "add<mode>3"
1040 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1041 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1042 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
1048 (define_expand "add<mode>3"
1049 [(set (match_dup:VDI 3)
1050 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1051 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
1052 (set (match_dup:VDI 5)
1053 (unspec:VDI [(match_dup 3)
1055 (match_dup:TI 4)] UNSPEC_SHUFB))
1056 (set (match_operand:VDI 0 "spu_reg_operand" "")
1057 (unspec:VDI [(match_dup 1)
1059 (match_dup 5)] UNSPEC_ADDX))]
1062 unsigned char pat[16] = {
1063 0x04, 0x05, 0x06, 0x07,
1064 0x80, 0x80, 0x80, 0x80,
1065 0x0c, 0x0d, 0x0e, 0x0f,
1066 0x80, 0x80, 0x80, 0x80
1068 operands[3] = gen_reg_rtx (<MODE>mode);
1069 operands[4] = gen_reg_rtx (TImode);
1070 operands[5] = gen_reg_rtx (<MODE>mode);
1071 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1074 (define_insn "cg_<mode>"
1075 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1076 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1077 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
1081 (define_insn "cgx_<mode>"
1082 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1083 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1084 (match_operand 2 "spu_reg_operand" "r")
1085 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1089 (define_insn "addx_<mode>"
1090 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1091 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1092 (match_operand 2 "spu_reg_operand" "r")
1093 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1098 ;; This is not the most efficient implementation of addti3.
1099 ;; We include this here because 1) the compiler needs it to be
1100 ;; defined as the word size is 128-bit and 2) sometimes gcc
1101 ;; substitutes an add for a constant left-shift. 2) is unlikely
1102 ;; because we also give addti3 a high cost. In case gcc does
1103 ;; generate TImode add, here is the code to do it.
1104 ;; operand 2 is a nonmemory because the compiler requires it.
1105 (define_insn "addti3"
1106 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1107 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1108 (match_operand:TI 2 "spu_nonmem_operand" "r")))
1109 (clobber (match_scratch:TI 3 "=&r"))]
1112 shlqbyi\t%3,%3,4\n\\
1114 shlqbyi\t%3,%3,4\n\\
1116 shlqbyi\t%0,%3,4\n\\
1118 [(set_attr "type" "multi0")
1119 (set_attr "length" "28")])
1121 (define_insn "add<mode>3"
1122 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1123 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1124 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1127 [(set_attr "type" "fp6")])
1129 (define_insn "add<mode>3"
1130 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1131 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1132 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1135 [(set_attr "type" "fpd")])
1140 (define_expand "subv16qi3"
1141 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1142 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1143 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1146 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1147 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1148 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1149 rtx rhs_and = gen_reg_rtx (V8HImode);
1150 rtx hi_char = gen_reg_rtx (V8HImode);
1151 rtx lo_char = gen_reg_rtx (V8HImode);
1152 rtx mask = gen_reg_rtx (V8HImode);
1154 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1155 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1156 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1157 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1158 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1162 (define_insn "sub<mode>3"
1163 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1164 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1165 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1171 (define_expand "sub<mode>3"
1172 [(set (match_dup:VDI 3)
1173 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1174 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1175 (set (match_dup:VDI 5)
1176 (unspec:VDI [(match_dup 3)
1178 (match_dup:TI 4)] UNSPEC_SHUFB))
1179 (set (match_operand:VDI 0 "spu_reg_operand" "")
1180 (unspec:VDI [(match_dup 1)
1182 (match_dup 5)] UNSPEC_SFX))]
1185 unsigned char pat[16] = {
1186 0x04, 0x05, 0x06, 0x07,
1187 0xc0, 0xc0, 0xc0, 0xc0,
1188 0x0c, 0x0d, 0x0e, 0x0f,
1189 0xc0, 0xc0, 0xc0, 0xc0
1191 operands[3] = gen_reg_rtx (<MODE>mode);
1192 operands[4] = gen_reg_rtx (TImode);
1193 operands[5] = gen_reg_rtx (<MODE>mode);
1194 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1197 (define_insn "bg_<mode>"
1198 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1199 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1200 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1204 (define_insn "bgx_<mode>"
1205 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1206 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1207 (match_operand 2 "spu_reg_operand" "r")
1208 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1212 (define_insn "sfx_<mode>"
1213 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1214 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1215 (match_operand 2 "spu_reg_operand" "r")
1216 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1220 (define_insn "subti3"
1221 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1222 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1223 (match_operand:TI 2 "spu_reg_operand" "r")))
1224 (clobber (match_scratch:TI 3 "=&r"))
1225 (clobber (match_scratch:TI 4 "=&r"))
1226 (clobber (match_scratch:TI 5 "=&r"))
1227 (clobber (match_scratch:TI 6 "=&r"))]
1233 shlqbyi\t%5,%3,4\n\\
1237 shlqbyi\t%5,%3,4\n\\
1241 shlqbyi\t%5,%3,4\n\\
1243 [(set_attr "type" "multi0")
1244 (set_attr "length" "56")])
1246 (define_insn "sub<mode>3"
1247 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1248 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1249 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1252 [(set_attr "type" "fp6")])
1254 (define_insn "sub<mode>3"
1255 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1256 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1257 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1260 [(set_attr "type" "fpd")])
1265 (define_expand "negv16qi2"
1266 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1267 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1270 rtx zero = gen_reg_rtx (V16QImode);
1271 emit_move_insn (zero, CONST0_RTX (V16QImode));
1272 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1276 (define_insn "neg<mode>2"
1277 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1278 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1282 (define_expand "negdi2"
1283 [(set (match_operand:DI 0 "spu_reg_operand" "")
1284 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1287 rtx zero = gen_reg_rtx(DImode);
1288 emit_move_insn(zero, GEN_INT(0));
1289 emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1293 (define_expand "negti2"
1294 [(set (match_operand:TI 0 "spu_reg_operand" "")
1295 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1298 rtx zero = gen_reg_rtx(TImode);
1299 emit_move_insn(zero, GEN_INT(0));
1300 emit_insn (gen_subti3(operands[0], zero, operands[1]));
1304 (define_expand "neg<mode>2"
1306 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1307 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1308 (use (match_dup 2))])]
1310 "operands[2] = gen_reg_rtx (<F2I>mode);
1311 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1313 (define_expand "neg<mode>2"
1315 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1316 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1317 (use (match_dup 2))])]
1319 "operands[2] = gen_reg_rtx (<F2I>mode);
1320 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
1322 (define_insn_and_split "_neg<mode>2"
1323 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1324 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1325 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1329 [(set (match_dup:<F2I> 3)
1330 (xor:<F2I> (match_dup:<F2I> 4)
1331 (match_dup:<F2I> 2)))]
1333 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1334 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1340 (define_expand "abs<mode>2"
1342 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1343 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1344 (use (match_dup 2))])]
1346 "operands[2] = gen_reg_rtx (<F2I>mode);
1347 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1349 (define_expand "abs<mode>2"
1351 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1352 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1353 (use (match_dup 2))])]
1355 "operands[2] = gen_reg_rtx (<F2I>mode);
1356 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
1358 (define_insn_and_split "_abs<mode>2"
1359 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1360 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1361 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1365 [(set (match_dup:<F2I> 3)
1366 (and:<F2I> (match_dup:<F2I> 4)
1367 (match_dup:<F2I> 2)))]
1369 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1370 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1376 (define_insn "mulhi3"
1377 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1378 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1379 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1384 [(set_attr "type" "fp7")])
1386 (define_expand "mulv8hi3"
1387 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1388 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1389 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1392 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1393 rtx low = gen_reg_rtx (V4SImode);
1394 rtx high = gen_reg_rtx (V4SImode);
1395 rtx shift = gen_reg_rtx (V4SImode);
1396 rtx mask = gen_reg_rtx (V4SImode);
1398 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1399 emit_insn (gen_vec_widen_smult_even_v8hi (high, operands[1], operands[2]));
1400 emit_insn (gen_vec_widen_smult_odd_v8hi (low, operands[1], operands[2]));
1401 emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1402 emit_insn (gen_selb (result, shift, low, mask));
1406 (define_expand "mul<mode>3"
1408 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1409 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1410 (match_operand:VSI 2 "spu_reg_operand" "")))
1411 (clobber (match_dup:VSI 3))
1412 (clobber (match_dup:VSI 4))
1413 (clobber (match_dup:VSI 5))
1414 (clobber (match_dup:VSI 6))])]
1417 operands[3] = gen_reg_rtx(<MODE>mode);
1418 operands[4] = gen_reg_rtx(<MODE>mode);
1419 operands[5] = gen_reg_rtx(<MODE>mode);
1420 operands[6] = gen_reg_rtx(<MODE>mode);
1423 (define_insn_and_split "_mulsi3"
1424 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1425 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1426 (match_operand:SI 2 "spu_arith_operand" "rK")))
1427 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1428 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1429 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1430 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1434 [(set (match_dup:SI 0)
1435 (mult:SI (match_dup:SI 1)
1438 HOST_WIDE_INT val = 0;
1439 rtx a = operands[3];
1440 rtx b = operands[4];
1441 rtx c = operands[5];
1442 rtx d = operands[6];
1443 if (GET_CODE(operands[2]) == CONST_INT)
1445 val = INTVAL(operands[2]);
1446 emit_move_insn(d, operands[2]);
1449 if (val && (val & 0xffff) == 0)
1451 emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1453 else if (val > 0 && val < 0x10000)
1455 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1456 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1457 emit_insn (gen_mpyu_si(c, operands[1], cst));
1458 emit_insn (gen_addsi3(operands[0], a, c));
1462 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1463 emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1464 emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1465 emit_insn (gen_addsi3(d, a, b));
1466 emit_insn (gen_addsi3(operands[0], d, c));
1471 (define_insn_and_split "_mulv4si3"
1472 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1473 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1474 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1475 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1476 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1477 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1478 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1482 [(set (match_dup:V4SI 0)
1483 (mult:V4SI (match_dup:V4SI 1)
1484 (match_dup:V4SI 2)))]
1486 rtx a = operands[3];
1487 rtx b = operands[4];
1488 rtx c = operands[5];
1489 rtx d = operands[6];
1490 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1491 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1492 emit_insn (gen_spu_mpyh(a, op1, op2));
1493 emit_insn (gen_spu_mpyh(b, op2, op1));
1494 emit_insn (gen_vec_widen_umult_odd_v8hi (c, op1, op2));
1495 emit_insn (gen_addv4si3(d, a, b));
1496 emit_insn (gen_addv4si3(operands[0], d, c));
1500 (define_insn "mulhisi3"
1501 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1502 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1503 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1506 [(set_attr "type" "fp7")])
1508 (define_insn "mulhisi3_imm"
1509 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1510 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1511 (match_operand:SI 2 "imm_K_operand" "K")))]
1514 [(set_attr "type" "fp7")])
1516 (define_insn "umulhisi3"
1517 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1518 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1519 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1522 [(set_attr "type" "fp7")])
1524 (define_insn "umulhisi3_imm"
1525 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1526 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1527 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1530 [(set_attr "type" "fp7")])
1532 (define_insn "mpyu_si"
1533 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1534 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1536 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1537 (const_int 65535))))]
1542 [(set_attr "type" "fp7")])
1544 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1545 ;; It's faster to do the multiplies in parallel then add them. If we
1546 ;; merge a multiply and add it prevents the multiplies from happening in
1548 (define_insn "mpya_si"
1549 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1550 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1551 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1552 (match_operand:SI 3 "spu_reg_operand" "r")))]
1555 [(set_attr "type" "fp7")])
1557 (define_insn "mpyh_si"
1558 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1559 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1561 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1562 (const_int 65535))))]
1565 [(set_attr "type" "fp7")])
1567 (define_insn "mpys_si"
1568 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1570 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1571 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1575 [(set_attr "type" "fp7")])
1577 (define_insn "mpyhh_si"
1578 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1579 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1581 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1585 [(set_attr "type" "fp7")])
1587 (define_insn "mpyhhu_si"
1588 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1589 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1591 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1595 [(set_attr "type" "fp7")])
1597 (define_insn "mpyhha_si"
1598 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1599 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1601 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1603 (match_operand:SI 3 "spu_reg_operand" "0")))]
1606 [(set_attr "type" "fp7")])
1608 (define_insn "mul<mode>3"
1609 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1610 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1611 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1614 [(set_attr "type" "fp<d6>")])
1616 (define_insn "fma<mode>4"
1617 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1618 (fma:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1619 (match_operand:VSF 2 "spu_reg_operand" "r")
1620 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1623 [(set_attr "type" "fp6")])
1625 ;; ??? The official description is (c - a*b), which is exactly (-a*b + c).
1626 ;; Note that this doesn't match the dfnms description. Incorrect?
1627 (define_insn "fnma<mode>4"
1628 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1630 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
1631 (match_operand:VSF 2 "spu_reg_operand" "r")
1632 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1635 [(set_attr "type" "fp6")])
1637 (define_insn "fms<mode>4"
1638 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1640 (match_operand:VSF 1 "spu_reg_operand" "r")
1641 (match_operand:VSF 2 "spu_reg_operand" "r")
1642 (neg:VSF (match_operand:VSF 3 "spu_reg_operand" "r"))))]
1645 [(set_attr "type" "fp6")])
1647 (define_insn "fma<mode>4"
1648 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1649 (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1650 (match_operand:VDF 2 "spu_reg_operand" "r")
1651 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1654 [(set_attr "type" "fpd")])
1656 (define_insn "fms<mode>4"
1657 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1659 (match_operand:VDF 1 "spu_reg_operand" "r")
1660 (match_operand:VDF 2 "spu_reg_operand" "r")
1661 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1664 [(set_attr "type" "fpd")])
1666 (define_insn "nfma<mode>4"
1667 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1669 (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1670 (match_operand:VDF 2 "spu_reg_operand" "r")
1671 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1674 [(set_attr "type" "fpd")])
1676 (define_insn "nfms<mode>4"
1677 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1680 (match_operand:VDF 1 "spu_reg_operand" "r")
1681 (match_operand:VDF 2 "spu_reg_operand" "r")
1682 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0")))))]
1685 [(set_attr "type" "fpd")])
1687 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
1688 (define_expand "fnma<mode>4"
1689 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1692 (match_operand:VDF 1 "spu_reg_operand" "")
1693 (match_operand:VDF 2 "spu_reg_operand" "")
1694 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "")))))]
1695 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1698 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
1699 (define_expand "fnms<mode>4"
1700 [(set (match_operand:VDF 0 "register_operand" "")
1703 (match_operand:VDF 1 "register_operand" "")
1704 (match_operand:VDF 2 "register_operand" "")
1705 (match_operand:VDF 3 "register_operand" ""))))]
1706 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1709 ;; mul highpart, used for divide by constant optimizations.
1711 (define_expand "smulsi3_highpart"
1712 [(set (match_operand:SI 0 "register_operand" "")
1715 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1716 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1720 rtx t0 = gen_reg_rtx (SImode);
1721 rtx t1 = gen_reg_rtx (SImode);
1722 rtx t2 = gen_reg_rtx (SImode);
1723 rtx t3 = gen_reg_rtx (SImode);
1724 rtx t4 = gen_reg_rtx (SImode);
1725 rtx t5 = gen_reg_rtx (SImode);
1726 rtx t6 = gen_reg_rtx (SImode);
1727 rtx t7 = gen_reg_rtx (SImode);
1728 rtx t8 = gen_reg_rtx (SImode);
1729 rtx t9 = gen_reg_rtx (SImode);
1730 rtx t11 = gen_reg_rtx (SImode);
1731 rtx t12 = gen_reg_rtx (SImode);
1732 rtx t14 = gen_reg_rtx (SImode);
1733 rtx t15 = gen_reg_rtx (HImode);
1734 rtx t16 = gen_reg_rtx (HImode);
1735 rtx t17 = gen_reg_rtx (HImode);
1736 rtx t18 = gen_reg_rtx (HImode);
1737 rtx t19 = gen_reg_rtx (SImode);
1738 rtx t20 = gen_reg_rtx (SImode);
1739 rtx t21 = gen_reg_rtx (SImode);
1740 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1741 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1742 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1743 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1745 rtx_insn *insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1746 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1747 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1748 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1749 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1750 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1751 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1752 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1754 /* Gen carry bits (in t9 and t11). */
1755 emit_insn (gen_addsi3 (t8, t2, t3));
1756 emit_insn (gen_cg_si (t9, t2, t3));
1757 emit_insn (gen_cg_si (t11, t8, t4));
1759 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1760 emit_insn (gen_addx_si (t12, t5, t6, t9));
1761 emit_insn (gen_addx_si (t14, t12, t7, t11));
1763 /* mpys treats both operands as signed when we really want it to treat
1764 the first operand as signed and the second operand as unsigned.
1765 The code below corrects for that difference. */
1766 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1767 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1768 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1769 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1770 emit_insn (gen_extendhisi2 (t19, t17));
1771 emit_insn (gen_extendhisi2 (t20, t18));
1772 emit_insn (gen_addsi3 (t21, t19, t20));
1773 emit_insn (gen_addsi3 (operands[0], t14, t21));
1774 unshare_all_rtl_in_chain (insn);
1778 (define_expand "umulsi3_highpart"
1779 [(set (match_operand:SI 0 "register_operand" "")
1782 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1783 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1788 rtx t0 = gen_reg_rtx (SImode);
1789 rtx t1 = gen_reg_rtx (SImode);
1790 rtx t2 = gen_reg_rtx (SImode);
1791 rtx t3 = gen_reg_rtx (SImode);
1792 rtx t4 = gen_reg_rtx (SImode);
1793 rtx t5 = gen_reg_rtx (SImode);
1794 rtx t6 = gen_reg_rtx (SImode);
1795 rtx t7 = gen_reg_rtx (SImode);
1796 rtx t8 = gen_reg_rtx (SImode);
1797 rtx t9 = gen_reg_rtx (SImode);
1798 rtx t10 = gen_reg_rtx (SImode);
1799 rtx t12 = gen_reg_rtx (SImode);
1800 rtx t13 = gen_reg_rtx (SImode);
1801 rtx t14 = gen_reg_rtx (SImode);
1802 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1803 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1804 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1806 rtx_insn *insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1807 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1808 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1809 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1810 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1811 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1812 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1813 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1814 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1816 /* Gen carry bits (in t10 and t12). */
1817 emit_insn (gen_addsi3 (t9, t1, t5));
1818 emit_insn (gen_cg_si (t10, t1, t5));
1819 emit_insn (gen_cg_si (t12, t9, t6));
1821 /* Gen high 32 bits in operand[0]. */
1822 emit_insn (gen_addx_si (t13, t4, t7, t10));
1823 emit_insn (gen_addx_si (t14, t13, t8, t12));
1824 emit_insn (gen_movsi (operands[0], t14));
1825 unshare_all_rtl_in_chain (insn);
1832 ;; Not necessarily the best implementation of divide but faster then
1833 ;; the default that gcc provides because this is inlined and it uses
1835 (define_insn "divmodsi4"
1836 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1837 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1838 (match_operand:SI 2 "spu_reg_operand" "r")))
1839 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1840 (mod:SI (match_dup 1)
1842 (clobber (match_scratch:SI 4 "=&r"))
1843 (clobber (match_scratch:SI 5 "=&r"))
1844 (clobber (match_scratch:SI 6 "=&r"))
1845 (clobber (match_scratch:SI 7 "=&r"))
1846 (clobber (match_scratch:SI 8 "=&r"))
1847 (clobber (match_scratch:SI 9 "=&r"))
1848 (clobber (match_scratch:SI 10 "=&r"))
1849 (clobber (match_scratch:SI 11 "=&r"))
1850 (clobber (match_scratch:SI 12 "=&r"))
1851 (clobber (reg:SI 130))]
1859 selb %8,%8,%1,%10\\n\\
1860 selb %9,%9,%2,%11\\n\\
1866 shlqbyi %3,%8,0\\n\\
1867 xor %11,%10,%11\\n\\
1871 1: or %12,%0,%5\\n\\
1872 rotqmbii %5,%5,-1\\n\\
1876 rotqmbii %4,%4,-1\\n\\
1877 selb %0,%12,%0,%6\\n\\
1879 selb %3,%7,%3,%6\\n\\
1883 selb %3,%8,%3,%10\\n\\
1885 [(set_attr "type" "multi0")
1886 (set_attr "length" "128")])
1888 (define_insn "udivmodsi4"
1889 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1890 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1891 (match_operand:SI 2 "spu_reg_operand" "r")))
1892 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1893 (umod:SI (match_dup 1)
1895 (clobber (match_scratch:SI 4 "=&r"))
1896 (clobber (match_scratch:SI 5 "=&r"))
1897 (clobber (match_scratch:SI 6 "=&r"))
1898 (clobber (match_scratch:SI 7 "=&r"))
1899 (clobber (match_scratch:SI 8 "=&r"))
1900 (clobber (reg:SI 130))]
1913 rotqmbii %5,%5,-1\\n\\
1917 rotqmbii %4,%4,-1\\n\\
1918 selb %0,%8,%0,%6\\n\\
1920 selb %3,%7,%3,%6\\n\\
1923 [(set_attr "type" "multi0")
1924 (set_attr "length" "80")])
1926 (define_expand "div<mode>3"
1928 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1929 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1930 (match_operand:VSF 2 "spu_reg_operand" "")))
1931 (clobber (match_scratch:VSF 3 ""))
1932 (clobber (match_scratch:VSF 4 ""))
1933 (clobber (match_scratch:VSF 5 ""))])]
1937 (define_insn_and_split "*div<mode>3_fast"
1938 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1939 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1940 (match_operand:VSF 2 "spu_reg_operand" "r")))
1941 (clobber (match_scratch:VSF 3 "=&r"))
1942 (clobber (match_scratch:VSF 4 "=&r"))
1943 (clobber (scratch:VSF))]
1944 "flag_unsafe_math_optimizations"
1947 [(set (match_dup:VSF 0)
1948 (div:VSF (match_dup:VSF 1)
1950 (clobber (match_dup:VSF 3))
1951 (clobber (match_dup:VSF 4))
1952 (clobber (scratch:VSF))]
1954 emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1955 emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1956 emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1957 emit_insn (gen_fnma<mode>4(operands[0], operands[4], operands[2], operands[1]));
1958 emit_insn (gen_fma<mode>4(operands[0], operands[0], operands[3], operands[4]));
1962 (define_insn_and_split "*div<mode>3_adjusted"
1963 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1964 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1965 (match_operand:VSF 2 "spu_reg_operand" "r")))
1966 (clobber (match_scratch:VSF 3 "=&r"))
1967 (clobber (match_scratch:VSF 4 "=&r"))
1968 (clobber (match_scratch:VSF 5 "=&r"))]
1969 "!flag_unsafe_math_optimizations"
1972 [(set (match_dup:VSF 0)
1973 (div:VSF (match_dup:VSF 1)
1975 (clobber (match_dup:VSF 3))
1976 (clobber (match_dup:VSF 4))
1977 (clobber (match_dup:VSF 5))]
1979 emit_insn (gen_frest_<mode> (operands[3], operands[2]));
1980 emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
1981 emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
1982 emit_insn (gen_fnma<mode>4 (operands[5], operands[4], operands[2], operands[1]));
1983 emit_insn (gen_fma<mode>4 (operands[3], operands[5], operands[3], operands[4]));
1985 /* Due to truncation error, the quotient result may be low by 1 ulp.
1986 Conditionally add one if the estimate is too small in magnitude. */
1988 emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
1989 spu_const (<F2I>mode, 0x80000000ULL));
1990 emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
1991 spu_const (<F2I>mode, 0x3f800000ULL));
1992 emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1994 emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
1995 gen_lowpart (<F2I>mode, operands[3]),
1996 spu_const (<F2I>mode, 1)));
1997 emit_insn (gen_fnma<mode>4 (operands[0], operands[2], operands[4], operands[1]));
1998 emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
1999 emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
2000 gen_lowpart (<F2I>mode, operands[0]),
2001 spu_const (<F2I>mode, -1)));
2002 emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
2009 (define_insn_and_split "sqrtsf2"
2010 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
2011 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
2012 (clobber (match_scratch:SF 2 "=&r"))
2013 (clobber (match_scratch:SF 3 "=&r"))
2014 (clobber (match_scratch:SF 4 "=&r"))
2015 (clobber (match_scratch:SF 5 "=&r"))]
2019 [(set (match_dup:SF 0)
2020 (sqrt:SF (match_dup:SF 1)))
2021 (clobber (match_dup:SF 2))
2022 (clobber (match_dup:SF 3))
2023 (clobber (match_dup:SF 4))
2024 (clobber (match_dup:SF 5))]
2026 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
2027 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
2028 emit_insn (gen_frsqest_sf(operands[2],operands[1]));
2029 emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
2030 emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
2031 emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
2032 emit_insn (gen_fnmasf4(operands[4],operands[2],operands[5],operands[4]));
2033 emit_insn (gen_fmasf4(operands[0],operands[4],operands[3],operands[5]));
2037 (define_insn "frest_<mode>"
2038 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2039 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
2042 [(set_attr "type" "shuf")])
2044 (define_insn "frsqest_<mode>"
2045 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2046 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
2049 [(set_attr "type" "shuf")])
2051 (define_insn "fi_<mode>"
2052 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2053 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
2054 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
2057 [(set_attr "type" "fp7")])
2062 (define_insn "and<mode>3"
2063 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2064 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2065 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
2069 and%j2i\t%0,%1,%J2")
2071 (define_insn "anddi3"
2072 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2073 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2074 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2078 and%k2i\t%0,%1,%K2")
2080 (define_insn "andti3"
2081 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2082 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2083 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2087 and%m2i\t%0,%1,%L2")
2089 (define_insn "andc_<mode>"
2090 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2091 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2092 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2096 (define_insn "nand_<mode>"
2097 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2098 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
2099 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
2106 (define_insn "ior<mode>3"
2107 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
2108 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2109 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2116 (define_insn "iordi3"
2117 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2118 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2119 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2126 (define_insn "iorti3"
2127 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2128 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2129 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2136 (define_insn "orc_<mode>"
2137 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2138 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2139 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2143 (define_insn "nor_<mode>"
2144 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2145 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2146 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2152 (define_insn "xor<mode>3"
2153 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2154 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2155 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2159 xor%j2i\t%0,%1,%J2")
2161 (define_insn "xordi3"
2162 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2163 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2164 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2168 xor%k2i\t%0,%1,%K2")
2170 (define_insn "xorti3"
2171 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2172 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2173 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2177 xor%m2i\t%0,%1,%L2")
2179 (define_insn "eqv_<mode>"
2180 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2181 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2182 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2188 (define_insn "one_cmpl<mode>2"
2189 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2190 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2197 (define_expand "selb"
2198 [(set (match_operand 0 "spu_reg_operand" "")
2199 (unspec [(match_operand 1 "spu_reg_operand" "")
2200 (match_operand 2 "spu_reg_operand" "")
2201 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2204 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2205 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2210 ;; This could be defined as a combination of logical operations, but at
2211 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2212 (define_insn "_selb"
2213 [(set (match_operand 0 "spu_reg_operand" "=r")
2214 (unspec [(match_operand 1 "spu_reg_operand" "r")
2215 (match_operand 2 "spu_reg_operand" "r")
2216 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2217 "GET_MODE(operands[0]) == GET_MODE(operands[1])
2218 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2219 "selb\t%0,%1,%2,%3")
2222 ;; Misc. byte/bit operations
2223 ;; clz/ctz/ffs/popcount/parity
2226 (define_insn "clz<mode>2"
2227 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2228 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2232 (define_expand "ctz<mode>2"
2234 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2235 (set (match_dup 3) (and:VSI (match_dup 1)
2237 (set (match_dup 4) (clz:VSI (match_dup 3)))
2238 (set (match_operand:VSI 0 "spu_reg_operand" "")
2239 (minus:VSI (match_dup 5) (match_dup 4)))]
2242 operands[2] = gen_reg_rtx (<MODE>mode);
2243 operands[3] = gen_reg_rtx (<MODE>mode);
2244 operands[4] = gen_reg_rtx (<MODE>mode);
2245 operands[5] = spu_const(<MODE>mode, 31);
2248 (define_expand "clrsb<mode>2"
2250 (gt:VSI (match_operand:VSI 1 "spu_reg_operand" "") (match_dup 5)))
2251 (set (match_dup 3) (not:VSI (xor:VSI (match_dup 1) (match_dup 2))))
2252 (set (match_dup 4) (clz:VSI (match_dup 3)))
2253 (set (match_operand:VSI 0 "spu_reg_operand")
2254 (plus:VSI (match_dup 4) (match_dup 5)))]
2257 operands[2] = gen_reg_rtx (<MODE>mode);
2258 operands[3] = gen_reg_rtx (<MODE>mode);
2259 operands[4] = gen_reg_rtx (<MODE>mode);
2260 operands[5] = spu_const(<MODE>mode, -1);
2263 (define_expand "ffs<mode>2"
2265 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2266 (set (match_dup 3) (and:VSI (match_dup 1)
2268 (set (match_dup 4) (clz:VSI (match_dup 3)))
2269 (set (match_operand:VSI 0 "spu_reg_operand" "")
2270 (minus:VSI (match_dup 5) (match_dup 4)))]
2273 operands[2] = gen_reg_rtx (<MODE>mode);
2274 operands[3] = gen_reg_rtx (<MODE>mode);
2275 operands[4] = gen_reg_rtx (<MODE>mode);
2276 operands[5] = spu_const(<MODE>mode, 32);
2279 (define_expand "popcountsi2"
2281 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2284 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2285 (set (match_operand:SI 0 "spu_reg_operand" "")
2286 (sign_extend:SI (match_dup 3)))]
2289 operands[2] = gen_reg_rtx (SImode);
2290 operands[3] = gen_reg_rtx (HImode);
2293 (define_expand "paritysi2"
2294 [(set (match_operand:SI 0 "spu_reg_operand" "")
2295 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2298 operands[2] = gen_reg_rtx (SImode);
2299 emit_insn (gen_popcountsi2(operands[2], operands[1]));
2300 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2304 (define_insn "cntb_si"
2305 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2306 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2310 [(set_attr "type" "fxb")])
2312 (define_insn "cntb_v16qi"
2313 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2314 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2318 [(set_attr "type" "fxb")])
2320 (define_insn "sumb_si"
2321 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2322 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2325 [(set_attr "type" "fxb")])
2330 (define_insn "<v>ashl<mode>3"
2331 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2332 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2333 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2337 shl<bh>i\t%0,%1,%<umask>2"
2338 [(set_attr "type" "fx3")])
2340 (define_insn_and_split "ashldi3"
2341 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2342 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2343 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2344 (clobber (match_scratch:SI 3 "=&r,X"))]
2348 [(set (match_dup:DI 0)
2349 (ashift:DI (match_dup:DI 1)
2352 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2353 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2354 rtx op2 = operands[2];
2355 rtx op3 = operands[3];
2357 if (GET_CODE (operands[2]) == REG)
2359 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2360 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2361 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2362 emit_insn (gen_shlqbi_ti (op0, op0, op3));
2366 HOST_WIDE_INT val = INTVAL (operands[2]);
2367 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2368 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2370 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2375 (define_expand "ashlti3"
2376 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2377 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2378 (match_operand:SI 2 "spu_nonmem_operand" "")))
2379 (clobber (match_dup:TI 3))])]
2381 "if (GET_CODE (operands[2]) == CONST_INT)
2383 emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2386 operands[3] = gen_reg_rtx (TImode);")
2388 (define_insn_and_split "ashlti3_imm"
2389 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2390 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2391 (match_operand:SI 2 "immediate_operand" "O,P")))]
2396 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2397 [(set (match_dup:TI 0)
2398 (ashift:TI (match_dup:TI 1)
2400 (set (match_dup:TI 0)
2401 (ashift:TI (match_dup:TI 0)
2404 HOST_WIDE_INT val = INTVAL(operands[2]);
2405 operands[3] = GEN_INT (val&7);
2406 operands[4] = GEN_INT (val&-8);
2408 [(set_attr "type" "shuf,shuf")])
2410 (define_insn_and_split "ashlti3_reg"
2411 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2412 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2413 (match_operand:SI 2 "spu_reg_operand" "r")))
2414 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2418 [(set (match_dup:TI 3)
2419 (ashift:TI (match_dup:TI 1)
2420 (and:SI (match_dup:SI 2)
2422 (set (match_dup:TI 0)
2423 (ashift:TI (match_dup:TI 3)
2424 (and:SI (match_dup:SI 2)
2428 (define_insn "shlqbybi_ti"
2429 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2430 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2431 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2437 [(set_attr "type" "shuf,shuf")])
2439 (define_insn "shlqbi_ti"
2440 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2441 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2442 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2448 [(set_attr "type" "shuf,shuf")])
2450 (define_insn "shlqby_ti"
2451 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2452 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2453 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2459 [(set_attr "type" "shuf,shuf")])
2464 (define_insn_and_split "<v>lshr<mode>3"
2465 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2466 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2467 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2468 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2472 rot<bh>mi\t%0,%1,-%<umask>2"
2473 "reload_completed && GET_CODE (operands[2]) == REG"
2474 [(set (match_dup:VHSI 3)
2475 (neg:VHSI (match_dup:VHSI 2)))
2476 (set (match_dup:VHSI 0)
2477 (lshiftrt:VHSI (match_dup:VHSI 1)
2478 (neg:VHSI (match_dup:VHSI 3))))]
2480 [(set_attr "type" "*,fx3")])
2482 (define_insn "<v>lshr<mode>3_imm"
2483 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2484 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2485 (match_operand:VHSI 2 "immediate_operand" "W")))]
2487 "rot<bh>mi\t%0,%1,-%<umask>2"
2488 [(set_attr "type" "fx3")])
2490 (define_insn "rotm_<mode>"
2491 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2492 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2493 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2497 rot<bh>mi\t%0,%1,-%<nmask>2"
2498 [(set_attr "type" "fx3")])
2500 (define_insn_and_split "lshr<mode>3"
2501 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2502 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2503 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2507 rotqmbyi\t%0,%1,-%h2
2508 rotqmbii\t%0,%1,-%e2"
2509 "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2510 [(set (match_dup:DTI 3)
2511 (lshiftrt:DTI (match_dup:DTI 1)
2513 (set (match_dup:DTI 0)
2514 (lshiftrt:DTI (match_dup:DTI 3)
2517 operands[3] = gen_reg_rtx (<MODE>mode);
2518 if (GET_CODE (operands[2]) == CONST_INT)
2520 HOST_WIDE_INT val = INTVAL(operands[2]);
2521 operands[4] = GEN_INT (val & 7);
2522 operands[5] = GEN_INT (val & -8);
2526 rtx t0 = gen_reg_rtx (SImode);
2527 rtx t1 = gen_reg_rtx (SImode);
2528 emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2529 emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2530 operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2531 operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2534 [(set_attr "type" "*,shuf,shuf")])
2536 (define_expand "shrqbybi_<mode>"
2537 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2538 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2539 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2544 if (GET_CODE (operands[2]) == CONST_INT)
2545 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2548 rtx t0 = gen_reg_rtx (SImode);
2549 emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2554 (define_insn "rotqmbybi_<mode>"
2555 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2556 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2557 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2563 rotqmbyi\t%0,%1,-%H2"
2564 [(set_attr "type" "shuf")])
2566 (define_insn_and_split "shrqbi_<mode>"
2567 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2568 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2569 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2571 (clobber (match_scratch:SI 3 "=&r,X"))]
2575 [(set (match_dup:DTI 0)
2576 (lshiftrt:DTI (match_dup:DTI 1)
2577 (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2579 if (GET_CODE (operands[2]) == CONST_INT)
2580 operands[3] = GEN_INT (-INTVAL (operands[2]));
2582 emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2584 [(set_attr "type" "shuf")])
2586 (define_insn "rotqmbi_<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 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2594 rotqmbii\t%0,%1,-%E2"
2595 [(set_attr "type" "shuf")])
2597 (define_expand "shrqby_<mode>"
2598 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2599 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2600 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2604 if (GET_CODE (operands[2]) == CONST_INT)
2605 operands[2] = GEN_INT (-INTVAL (operands[2]));
2608 rtx t0 = gen_reg_rtx (SImode);
2609 emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2614 (define_insn "rotqmby_<mode>"
2615 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2616 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2617 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2622 rotqmbyi\t%0,%1,-%F2"
2623 [(set_attr "type" "shuf")])
2628 (define_insn_and_split "<v>ashr<mode>3"
2629 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2630 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2631 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2632 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2636 rotma<bh>i\t%0,%1,-%<umask>2"
2637 "reload_completed && GET_CODE (operands[2]) == REG"
2638 [(set (match_dup:VHSI 3)
2639 (neg:VHSI (match_dup:VHSI 2)))
2640 (set (match_dup:VHSI 0)
2641 (ashiftrt:VHSI (match_dup:VHSI 1)
2642 (neg:VHSI (match_dup:VHSI 3))))]
2644 [(set_attr "type" "*,fx3")])
2646 (define_insn "<v>ashr<mode>3_imm"
2647 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2648 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2649 (match_operand:VHSI 2 "immediate_operand" "W")))]
2651 "rotma<bh>i\t%0,%1,-%<umask>2"
2652 [(set_attr "type" "fx3")])
2655 (define_insn "rotma_<mode>"
2656 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2657 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2658 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2662 rotma<bh>i\t%0,%1,-%<nmask>2"
2663 [(set_attr "type" "fx3")])
2665 (define_insn_and_split "ashrdi3"
2666 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2667 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2668 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2669 (clobber (match_scratch:TI 3 "=&r,&r"))
2670 (clobber (match_scratch:TI 4 "=&r,&r"))
2671 (clobber (match_scratch:SI 5 "=&r,&r"))]
2675 [(set (match_dup:DI 0)
2676 (ashiftrt:DI (match_dup:DI 1)
2679 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2680 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2681 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2682 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2683 rtx op2 = operands[2];
2684 rtx op3 = operands[3];
2685 rtx op4 = operands[4];
2686 rtx op5 = operands[5];
2688 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2690 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2691 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2692 emit_insn (gen_spu_fsm (op0v, op0s));
2694 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2696 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2697 HOST_WIDE_INT val = INTVAL (op2);
2698 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2699 emit_insn (gen_spu_xswd (op0d, op0v));
2701 emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2705 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2706 unsigned char arr[16] = {
2707 0xff, 0xff, 0xff, 0xff,
2708 0xff, 0xff, 0xff, 0xff,
2709 0x00, 0x00, 0x00, 0x00,
2710 0x00, 0x00, 0x00, 0x00
2713 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2714 emit_move_insn (op4, array_to_constant (TImode, arr));
2715 emit_insn (gen_spu_fsm (op3v, op5));
2717 if (GET_CODE (operands[2]) == REG)
2719 emit_insn (gen_selb (op4, op3, op1, op4));
2720 emit_insn (gen_negsi2 (op5, op2));
2721 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2722 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2726 HOST_WIDE_INT val = -INTVAL (op2);
2727 emit_insn (gen_selb (op0, op3, op1, op4));
2729 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2731 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2738 (define_insn_and_split "ashrti3"
2739 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2740 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2741 (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2745 [(set (match_dup:TI 0)
2746 (ashiftrt:TI (match_dup:TI 1)
2749 rtx sign_shift = gen_reg_rtx (SImode);
2750 rtx sign_mask = gen_reg_rtx (TImode);
2751 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2752 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2753 rtx t = gen_reg_rtx (TImode);
2754 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2755 emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2756 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2757 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2758 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2759 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2763 ;; fsm is used after rotam to replicate the sign across the whole register.
2764 (define_insn "fsm_ti"
2765 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2766 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2769 [(set_attr "type" "shuf")])
2774 (define_insn "<v>rotl<mode>3"
2775 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2776 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2777 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2781 rot<bh>i\t%0,%1,%<umask>2"
2782 [(set_attr "type" "fx3")])
2784 (define_insn "rotlti3"
2785 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2786 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2787 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2790 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2793 rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2794 [(set_attr "length" "8,4,4,8")
2795 (set_attr "type" "multi1,shuf,shuf,multi1")])
2797 (define_insn "rotqbybi_ti"
2798 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2799 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2800 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2806 [(set_attr "type" "shuf,shuf")])
2808 (define_insn "rotqby_ti"
2809 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2810 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2811 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2817 [(set_attr "type" "shuf,shuf")])
2819 (define_insn "rotqbi_ti"
2820 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2821 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2822 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2828 [(set_attr "type" "shuf,shuf")])
2831 ;; struct extract/insert
2832 ;; We handle mem's because GCC will generate invalid SUBREG's
2833 ;; and inefficient code.
2835 (define_expand "extv"
2836 [(set (match_operand:TI 0 "register_operand" "")
2837 (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2838 (match_operand:SI 2 "const_int_operand" "")
2839 (match_operand:SI 3 "const_int_operand" "")))]
2842 spu_expand_extv (operands, 0);
2846 (define_expand "extzv"
2847 [(set (match_operand:TI 0 "register_operand" "")
2848 (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2849 (match_operand:SI 2 "const_int_operand" "")
2850 (match_operand:SI 3 "const_int_operand" "")))]
2853 spu_expand_extv (operands, 1);
2857 (define_expand "insv"
2858 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2859 (match_operand:SI 1 "const_int_operand" "")
2860 (match_operand:SI 2 "const_int_operand" ""))
2861 (match_operand 3 "nonmemory_operand" ""))]
2864 if (INTVAL (operands[1]) + INTVAL (operands[2])
2865 > GET_MODE_BITSIZE (GET_MODE (operands[0])))
2867 spu_expand_insv(operands);
2871 ;; Simplify a number of patterns that get generated by extv, extzv,
2873 (define_insn_and_split "trunc_shr_ti<mode>"
2874 [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2875 (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2882 spu_split_convert (operands);
2885 [(set_attr "type" "convert")
2886 (set_attr "length" "0")])
2888 (define_insn_and_split "trunc_shr_tidi"
2889 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2890 (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2897 spu_split_convert (operands);
2900 [(set_attr "type" "convert")
2901 (set_attr "length" "0")])
2903 (define_insn_and_split "shl_ext_<mode>ti"
2904 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2905 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2912 spu_split_convert (operands);
2915 [(set_attr "type" "convert")
2916 (set_attr "length" "0")])
2918 (define_insn_and_split "shl_ext_diti"
2919 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2920 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2927 spu_split_convert (operands);
2930 [(set_attr "type" "convert")
2931 (set_attr "length" "0")])
2933 (define_insn "sext_trunc_lshr_tiqisi"
2934 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2935 (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2936 (const_int 120)]))))]
2939 [(set_attr "type" "fx3")])
2941 (define_insn "zext_trunc_lshr_tiqisi"
2942 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2943 (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2944 (const_int 120)]))))]
2947 [(set_attr "type" "fx3")])
2949 (define_insn "sext_trunc_lshr_tihisi"
2950 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2951 (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2952 (const_int 112)]))))]
2955 [(set_attr "type" "fx3")])
2957 (define_insn "zext_trunc_lshr_tihisi"
2958 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2959 (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2960 (const_int 112)]))))]
2963 [(set_attr "type" "fx3")])
2966 ;; String/block move insn.
2967 ;; Argument 0 is the destination
2968 ;; Argument 1 is the source
2969 ;; Argument 2 is the length
2970 ;; Argument 3 is the alignment
2972 (define_expand "movstrsi"
2973 [(parallel [(set (match_operand:BLK 0 "" "")
2974 (match_operand:BLK 1 "" ""))
2975 (use (match_operand:SI 2 "" ""))
2976 (use (match_operand:SI 3 "" ""))])]
2980 if (spu_expand_block_move (operands))
2989 (define_insn "indirect_jump"
2990 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2993 [(set_attr "type" "br")])
2997 (label_ref (match_operand 0 "" "")))]
3000 [(set_attr "type" "br")])
3005 ;; This will be used for leaf functions, that don't save any regs and
3006 ;; don't have locals on stack, maybe... that is for functions that
3007 ;; don't change $sp and don't need to save $lr.
3008 (define_expand "return"
3013 ;; used in spu_expand_epilogue to generate return from a function and
3014 ;; explicitly set use of $lr.
3016 (define_insn "_return"
3020 [(set_attr "type" "br")])
3026 (define_insn "ceq_<mode>"
3027 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3028 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3029 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3033 ceq<bh>i\t%0,%1,%2")
3035 (define_insn_and_split "ceq_di"
3036 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3037 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
3038 (match_operand:DI 2 "spu_reg_operand" "r")))]
3042 [(set (match_dup:SI 0)
3043 (eq:SI (match_dup:DI 1)
3046 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3047 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3048 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3049 emit_insn (gen_ceq_v4si (op0, op1, op2));
3050 emit_insn (gen_spu_gb (op0, op0));
3051 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
3056 ;; We provide the TI compares for completeness and because some parts of
3057 ;; gcc/libgcc use them, even though user code might never see it.
3058 (define_insn "ceq_ti"
3059 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3060 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
3061 (match_operand:TI 2 "spu_reg_operand" "r")))]
3063 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
3064 [(set_attr "type" "multi0")
3065 (set_attr "length" "12")])
3067 (define_insn "ceq_<mode>"
3068 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3069 (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3070 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3074 (define_insn "cmeq_<mode>"
3075 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3076 (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3077 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3081 ;; These implementations will ignore checking of NaN or INF if
3082 ;; compiled with option -ffinite-math-only.
3083 (define_expand "ceq_df"
3084 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3085 (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
3086 (match_operand:DF 2 "const_zero_operand" "i")))]
3089 if (spu_arch == PROCESSOR_CELL)
3091 rtx ra = gen_reg_rtx (V4SImode);
3092 rtx rb = gen_reg_rtx (V4SImode);
3093 rtx temp = gen_reg_rtx (TImode);
3094 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3095 rtx temp2 = gen_reg_rtx (V4SImode);
3096 rtx biteq = gen_reg_rtx (V4SImode);
3097 rtx ahi_inf = gen_reg_rtx (V4SImode);
3098 rtx a_nan = gen_reg_rtx (V4SImode);
3099 rtx a_abs = gen_reg_rtx (V4SImode);
3100 rtx b_abs = gen_reg_rtx (V4SImode);
3101 rtx iszero = gen_reg_rtx (V4SImode);
3102 rtx sign_mask = gen_reg_rtx (V4SImode);
3103 rtx nan_mask = gen_reg_rtx (V4SImode);
3104 rtx hihi_promote = gen_reg_rtx (TImode);
3105 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3106 0x7FFFFFFF, 0xFFFFFFFF);
3108 emit_move_insn (sign_mask, pat);
3109 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3111 emit_move_insn (nan_mask, pat);
3112 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3113 0x08090A0B, 0x18191A1B);
3114 emit_move_insn (hihi_promote, pat);
3116 emit_insn (gen_spu_convert (ra, operands[1]));
3117 emit_insn (gen_spu_convert (rb, operands[2]));
3118 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3119 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3121 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3123 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3124 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3125 if (!flag_finite_math_only)
3127 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3128 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3129 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3131 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3132 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3134 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3135 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3136 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3138 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3139 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3140 if (!flag_finite_math_only)
3142 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3144 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3149 (define_insn "ceq_<mode>_celledp"
3150 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3151 (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3152 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3153 "spu_arch == PROCESSOR_CELLEDP"
3155 [(set_attr "type" "fpd")])
3157 (define_insn "cmeq_<mode>_celledp"
3158 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3159 (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3160 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3161 "spu_arch == PROCESSOR_CELLEDP"
3163 [(set_attr "type" "fpd")])
3165 (define_expand "ceq_v2df"
3166 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3167 (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3168 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3171 if (spu_arch == PROCESSOR_CELL)
3173 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3174 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3175 rtx temp = gen_reg_rtx (TImode);
3176 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3177 rtx temp2 = gen_reg_rtx (V4SImode);
3178 rtx biteq = gen_reg_rtx (V4SImode);
3179 rtx ahi_inf = gen_reg_rtx (V4SImode);
3180 rtx a_nan = gen_reg_rtx (V4SImode);
3181 rtx a_abs = gen_reg_rtx (V4SImode);
3182 rtx b_abs = gen_reg_rtx (V4SImode);
3183 rtx iszero = gen_reg_rtx (V4SImode);
3184 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3185 0x7FFFFFFF, 0xFFFFFFFF);
3186 rtx sign_mask = gen_reg_rtx (V4SImode);
3187 rtx nan_mask = gen_reg_rtx (V4SImode);
3188 rtx hihi_promote = gen_reg_rtx (TImode);
3190 emit_move_insn (sign_mask, pat);
3191 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3193 emit_move_insn (nan_mask, pat);
3194 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3195 0x08090A0B, 0x18191A1B);
3196 emit_move_insn (hihi_promote, pat);
3198 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3199 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3201 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3202 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3203 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3204 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3205 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3206 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3208 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3209 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3210 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3211 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3212 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3214 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3215 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3216 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3217 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3222 (define_expand "cmeq_v2df"
3223 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3224 (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3225 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3228 if (spu_arch == PROCESSOR_CELL)
3230 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3231 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3232 rtx temp = gen_reg_rtx (TImode);
3233 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3234 rtx temp2 = gen_reg_rtx (V4SImode);
3235 rtx biteq = gen_reg_rtx (V4SImode);
3236 rtx ahi_inf = gen_reg_rtx (V4SImode);
3237 rtx a_nan = gen_reg_rtx (V4SImode);
3238 rtx a_abs = gen_reg_rtx (V4SImode);
3239 rtx b_abs = gen_reg_rtx (V4SImode);
3241 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3242 0x7FFFFFFF, 0xFFFFFFFF);
3243 rtx sign_mask = gen_reg_rtx (V4SImode);
3244 rtx nan_mask = gen_reg_rtx (V4SImode);
3245 rtx hihi_promote = gen_reg_rtx (TImode);
3247 emit_move_insn (sign_mask, pat);
3249 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3251 emit_move_insn (nan_mask, pat);
3252 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3253 0x08090A0B, 0x18191A1B);
3254 emit_move_insn (hihi_promote, pat);
3256 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3257 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3258 emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3259 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3261 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3262 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3263 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3264 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3266 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3267 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3268 emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3269 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3277 (define_insn "cgt_<mode>"
3278 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3279 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3280 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3284 cgt<bh>i\t%0,%1,%2")
3286 (define_insn "cgt_di_m1"
3287 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3288 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3293 (define_insn_and_split "cgt_di"
3294 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3295 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3296 (match_operand:DI 2 "spu_reg_operand" "r")))
3297 (clobber (match_scratch:V4SI 3 "=&r"))
3298 (clobber (match_scratch:V4SI 4 "=&r"))
3299 (clobber (match_scratch:V4SI 5 "=&r"))]
3303 [(set (match_dup:SI 0)
3304 (gt:SI (match_dup:DI 1)
3307 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3308 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3309 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3310 rtx op3 = operands[3];
3311 rtx op4 = operands[4];
3312 rtx op5 = operands[5];
3313 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3314 emit_insn (gen_clgt_v4si (op3, op1, op2));
3315 emit_insn (gen_ceq_v4si (op4, op1, op2));
3316 emit_insn (gen_cgt_v4si (op5, op1, op2));
3317 emit_insn (gen_spu_xswd (op3d, op3));
3318 emit_insn (gen_selb (op0, op5, op3, op4));
3322 (define_insn "cgt_ti_m1"
3323 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3324 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3329 (define_insn "cgt_ti"
3330 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3331 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3332 (match_operand:TI 2 "spu_reg_operand" "r")))
3333 (clobber (match_scratch:V4SI 3 "=&r"))
3334 (clobber (match_scratch:V4SI 4 "=&r"))
3335 (clobber (match_scratch:V4SI 5 "=&r"))]
3341 selb\t%0,%4,%0,%3\;\
3343 selb\t%0,%4,%0,%3\;\
3346 [(set_attr "type" "multi0")
3347 (set_attr "length" "36")])
3349 (define_insn "cgt_<mode>"
3350 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3351 (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3352 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3356 (define_insn "cmgt_<mode>"
3357 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3358 (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3359 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3363 (define_expand "cgt_df"
3364 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3365 (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3366 (match_operand:DF 2 "const_zero_operand" "i")))]
3369 if (spu_arch == PROCESSOR_CELL)
3371 rtx ra = gen_reg_rtx (V4SImode);
3372 rtx rb = gen_reg_rtx (V4SImode);
3373 rtx zero = gen_reg_rtx (V4SImode);
3374 rtx temp = gen_reg_rtx (TImode);
3375 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3376 rtx temp2 = gen_reg_rtx (V4SImode);
3377 rtx hi_inf = gen_reg_rtx (V4SImode);
3378 rtx a_nan = gen_reg_rtx (V4SImode);
3379 rtx b_nan = gen_reg_rtx (V4SImode);
3380 rtx a_abs = gen_reg_rtx (V4SImode);
3381 rtx b_abs = gen_reg_rtx (V4SImode);
3382 rtx asel = gen_reg_rtx (V4SImode);
3383 rtx bsel = gen_reg_rtx (V4SImode);
3384 rtx abor = gen_reg_rtx (V4SImode);
3385 rtx bbor = gen_reg_rtx (V4SImode);
3386 rtx gt_hi = gen_reg_rtx (V4SImode);
3387 rtx gt_lo = gen_reg_rtx (V4SImode);
3388 rtx sign_mask = gen_reg_rtx (V4SImode);
3389 rtx nan_mask = gen_reg_rtx (V4SImode);
3390 rtx hi_promote = gen_reg_rtx (TImode);
3391 rtx borrow_shuffle = gen_reg_rtx (TImode);
3393 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3394 0x7FFFFFFF, 0xFFFFFFFF);
3395 emit_move_insn (sign_mask, pat);
3396 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3398 emit_move_insn (nan_mask, pat);
3399 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3400 0x08090A0B, 0x08090A0B);
3401 emit_move_insn (hi_promote, pat);
3402 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3403 0x0C0D0E0F, 0xC0C0C0C0);
3404 emit_move_insn (borrow_shuffle, pat);
3406 emit_insn (gen_spu_convert (ra, operands[1]));
3407 emit_insn (gen_spu_convert (rb, operands[2]));
3408 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3409 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3411 if (!flag_finite_math_only)
3413 /* check if ra is NaN */
3414 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3415 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3416 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3418 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3419 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3420 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3422 /* check if rb is NaN */
3423 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3424 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3425 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3427 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3428 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3429 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3431 /* check if ra or rb is NaN */
3432 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3434 emit_move_insn (zero, CONST0_RTX (V4SImode));
3435 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3436 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3437 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3438 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3439 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3440 emit_insn (gen_selb (abor, a_abs, abor, asel));
3442 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3443 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3444 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3445 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3446 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3447 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3449 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3450 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3451 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3452 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3454 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3455 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3456 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3457 if (!flag_finite_math_only)
3459 /* correct for NaNs */
3460 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3462 emit_insn (gen_spu_convert (operands[0], temp2));
3467 (define_insn "cgt_<mode>_celledp"
3468 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3469 (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3470 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3471 "spu_arch == PROCESSOR_CELLEDP"
3473 [(set_attr "type" "fpd")])
3475 (define_insn "cmgt_<mode>_celledp"
3476 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3477 (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3478 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3479 "spu_arch == PROCESSOR_CELLEDP"
3481 [(set_attr "type" "fpd")])
3483 (define_expand "cgt_v2df"
3484 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3485 (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3486 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3489 if (spu_arch == PROCESSOR_CELL)
3491 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3492 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3493 rtx zero = gen_reg_rtx (V4SImode);
3494 rtx temp = gen_reg_rtx (TImode);
3495 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3496 rtx temp2 = gen_reg_rtx (V4SImode);
3497 rtx hi_inf = gen_reg_rtx (V4SImode);
3498 rtx a_nan = gen_reg_rtx (V4SImode);
3499 rtx b_nan = gen_reg_rtx (V4SImode);
3500 rtx a_abs = gen_reg_rtx (V4SImode);
3501 rtx b_abs = gen_reg_rtx (V4SImode);
3502 rtx asel = gen_reg_rtx (V4SImode);
3503 rtx bsel = gen_reg_rtx (V4SImode);
3504 rtx abor = gen_reg_rtx (V4SImode);
3505 rtx bbor = gen_reg_rtx (V4SImode);
3506 rtx gt_hi = gen_reg_rtx (V4SImode);
3507 rtx gt_lo = gen_reg_rtx (V4SImode);
3508 rtx sign_mask = gen_reg_rtx (V4SImode);
3509 rtx nan_mask = gen_reg_rtx (V4SImode);
3510 rtx hi_promote = gen_reg_rtx (TImode);
3511 rtx borrow_shuffle = gen_reg_rtx (TImode);
3512 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3513 0x7FFFFFFF, 0xFFFFFFFF);
3514 emit_move_insn (sign_mask, pat);
3515 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3517 emit_move_insn (nan_mask, pat);
3518 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3519 0x08090A0B, 0x08090A0B);
3520 emit_move_insn (hi_promote, pat);
3521 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3522 0x0C0D0E0F, 0xC0C0C0C0);
3523 emit_move_insn (borrow_shuffle, pat);
3525 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3526 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3527 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3528 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3530 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3531 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3532 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3533 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3534 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3535 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3536 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3538 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3539 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3540 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3541 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3542 emit_move_insn (zero, CONST0_RTX (V4SImode));
3543 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3544 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3545 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3546 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3547 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3548 emit_insn (gen_selb (abor, a_abs, abor, asel));
3549 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3550 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3551 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3552 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3553 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3554 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3555 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3556 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3557 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3558 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3560 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3561 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3563 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3564 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3565 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3570 (define_expand "cmgt_v2df"
3571 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3572 (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3573 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3576 if (spu_arch == PROCESSOR_CELL)
3578 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3579 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3580 rtx temp = gen_reg_rtx (TImode);
3581 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3582 rtx temp2 = gen_reg_rtx (V4SImode);
3583 rtx hi_inf = gen_reg_rtx (V4SImode);
3584 rtx a_nan = gen_reg_rtx (V4SImode);
3585 rtx b_nan = gen_reg_rtx (V4SImode);
3586 rtx a_abs = gen_reg_rtx (V4SImode);
3587 rtx b_abs = gen_reg_rtx (V4SImode);
3588 rtx gt_hi = gen_reg_rtx (V4SImode);
3589 rtx gt_lo = gen_reg_rtx (V4SImode);
3590 rtx sign_mask = gen_reg_rtx (V4SImode);
3591 rtx nan_mask = gen_reg_rtx (V4SImode);
3592 rtx hi_promote = gen_reg_rtx (TImode);
3593 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3594 0x7FFFFFFF, 0xFFFFFFFF);
3595 emit_move_insn (sign_mask, pat);
3596 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3598 emit_move_insn (nan_mask, pat);
3599 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3600 0x08090A0B, 0x08090A0B);
3601 emit_move_insn (hi_promote, pat);
3603 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3604 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3605 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3606 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3608 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3609 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3610 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3611 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3612 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3613 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3614 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3616 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3617 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3618 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3619 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3621 emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3622 emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3623 emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3624 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3626 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3627 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3628 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3629 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3630 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3638 (define_insn "clgt_<mode>"
3639 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3640 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3641 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3645 clgt<bh>i\t%0,%1,%2")
3647 (define_insn_and_split "clgt_di"
3648 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3649 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3650 (match_operand:DI 2 "spu_reg_operand" "r")))
3651 (clobber (match_scratch:V4SI 3 "=&r"))
3652 (clobber (match_scratch:V4SI 4 "=&r"))
3653 (clobber (match_scratch:V4SI 5 "=&r"))]
3657 [(set (match_dup:SI 0)
3658 (gtu:SI (match_dup:DI 1)
3661 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3662 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3663 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3664 rtx op3 = operands[3];
3665 rtx op4 = operands[4];
3666 rtx op5 = operands[5];
3667 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3668 emit_insn (gen_clgt_v4si (op3, op1, op2));
3669 emit_insn (gen_ceq_v4si (op4, op1, op2));
3670 emit_insn (gen_spu_xswd (op5d, op3));
3671 emit_insn (gen_selb (op0, op3, op5, op4));
3675 (define_insn "clgt_ti"
3676 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3677 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3678 (match_operand:TI 2 "spu_reg_operand" "r")))
3679 (clobber (match_scratch:V4SI 3 "=&r"))
3680 (clobber (match_scratch:V4SI 4 "=&r"))]
3685 selb\t%0,%4,%0,%3\;\
3687 selb\t%0,%4,%0,%3\;\
3690 [(set_attr "type" "multi0")
3691 (set_attr "length" "32")])
3695 (define_insn "dftsv_celledp"
3696 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3697 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3698 (match_operand:SI 2 "const_int_operand" "i")]
3700 "spu_arch == PROCESSOR_CELLEDP"
3702 [(set_attr "type" "fpd")])
3704 (define_expand "dftsv"
3705 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3706 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3707 (match_operand:SI 2 "const_int_operand" "i")]
3711 if (spu_arch == PROCESSOR_CELL)
3713 rtx result = gen_reg_rtx (V4SImode);
3714 emit_move_insn (result, CONST0_RTX (V4SImode));
3716 if (INTVAL (operands[2]))
3718 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3719 rtx abs = gen_reg_rtx (V4SImode);
3720 rtx sign = gen_reg_rtx (V4SImode);
3721 rtx temp = gen_reg_rtx (TImode);
3722 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3723 rtx temp2 = gen_reg_rtx (V4SImode);
3724 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3725 0x7FFFFFFF, 0xFFFFFFFF);
3726 rtx sign_mask = gen_reg_rtx (V4SImode);
3727 rtx hi_promote = gen_reg_rtx (TImode);
3728 emit_move_insn (sign_mask, pat);
3729 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3730 0x08090A0B, 0x08090A0B);
3731 emit_move_insn (hi_promote, pat);
3733 emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3734 emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3735 emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3737 /* NaN or +inf or -inf */
3738 if (INTVAL (operands[2]) & 0x70)
3740 rtx nan_mask = gen_reg_rtx (V4SImode);
3741 rtx isinf = gen_reg_rtx (V4SImode);
3742 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3744 emit_move_insn (nan_mask, pat);
3745 emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3748 if (INTVAL (operands[2]) & 0x40)
3750 rtx isnan = gen_reg_rtx (V4SImode);
3751 emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3752 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3754 emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3755 emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3756 emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3757 emit_insn (gen_iorv4si3 (result, result, isnan));
3760 if (INTVAL (operands[2]) & 0x30)
3762 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3764 emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3765 emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3768 if (INTVAL (operands[2]) & 0x20)
3770 emit_insn (gen_andc_v4si (temp2, isinf, sign));
3771 emit_insn (gen_iorv4si3 (result, result, temp2));
3774 if (INTVAL (operands[2]) & 0x10)
3776 emit_insn (gen_andv4si3 (temp2, isinf, sign));
3777 emit_insn (gen_iorv4si3 (result, result, temp2));
3783 if (INTVAL (operands[2]) & 0xF)
3785 rtx iszero = gen_reg_rtx (V4SImode);
3786 emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3787 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3789 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3792 if (INTVAL (operands[2]) & 0x3)
3794 rtx isdenorm = gen_reg_rtx (V4SImode);
3795 rtx denorm_mask = gen_reg_rtx (V4SImode);
3796 emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3797 emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3798 emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3799 emit_insn (gen_shufb (isdenorm, isdenorm,
3800 isdenorm, hi_promote));
3802 if (INTVAL (operands[2]) & 0x2)
3804 emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3805 emit_insn (gen_iorv4si3 (result, result, temp2));
3808 if (INTVAL (operands[2]) & 0x1)
3810 emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3811 emit_insn (gen_iorv4si3 (result, result, temp2));
3816 if (INTVAL (operands[2]) & 0xC)
3818 emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3820 if (INTVAL (operands[2]) & 0x8)
3822 emit_insn (gen_andc_v4si (temp2, iszero, sign));
3823 emit_insn (gen_iorv4si3 (result, result, temp2));
3826 if (INTVAL (operands[2]) & 0x4)
3828 emit_insn (gen_andv4si3 (temp2, iszero, sign));
3829 emit_insn (gen_iorv4si3 (result, result, temp2));
3834 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3844 (if_then_else (match_operator 1 "branch_comparison_operator"
3846 "spu_reg_operand" "r")
3848 (label_ref (match_operand 0 "" ""))
3852 [(set_attr "type" "br")])
3856 (if_then_else (match_operator 0 "branch_comparison_operator"
3858 "spu_reg_operand" "r")
3864 [(set_attr "type" "br")])
3868 (if_then_else (match_operator 1 "branch_comparison_operator"
3870 "spu_reg_operand" "r")
3873 (label_ref (match_operand 0 "" ""))))]
3876 [(set_attr "type" "br")])
3880 (if_then_else (match_operator 0 "branch_comparison_operator"
3882 "spu_reg_operand" "r")
3888 [(set_attr "type" "br")])
3891 ;; vector conditional compare patterns
3892 (define_expand "vcond<mode><mode>"
3893 [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3895 (match_operator 3 "comparison_operator"
3896 [(match_operand:VCMP 4 "spu_reg_operand" "r")
3897 (match_operand:VCMP 5 "spu_reg_operand" "r")])
3898 (match_operand:VCMP 1 "spu_reg_operand" "r")
3899 (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3902 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3903 operands[3], operands[4], operands[5]))
3909 (define_expand "vcondu<mode><mode>"
3910 [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3912 (match_operator 3 "comparison_operator"
3913 [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3914 (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3915 (match_operand:VCMPU 1 "spu_reg_operand" "r")
3916 (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3919 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3920 operands[3], operands[4], operands[5]))
3927 ;; branch on condition
3929 (define_expand "cbranch<mode>4"
3930 [(use (match_operator 0 "ordered_comparison_operator"
3931 [(match_operand:VQHSI 1 "spu_reg_operand" "")
3932 (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3933 (use (match_operand 3 ""))]
3935 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3937 (define_expand "cbranch<mode>4"
3938 [(use (match_operator 0 "ordered_comparison_operator"
3939 [(match_operand:DTI 1 "spu_reg_operand" "")
3940 (match_operand:DTI 2 "spu_reg_operand" "")]))
3941 (use (match_operand 3 ""))]
3943 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3945 (define_expand "cbranch<mode>4"
3946 [(use (match_operator 0 "ordered_comparison_operator"
3947 [(match_operand:VSF 1 "spu_reg_operand" "")
3948 (match_operand:VSF 2 "spu_reg_operand" "")]))
3949 (use (match_operand 3 ""))]
3951 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3953 (define_expand "cbranchdf4"
3954 [(use (match_operator 0 "ordered_comparison_operator"
3955 [(match_operand:DF 1 "spu_reg_operand" "")
3956 (match_operand:DF 2 "spu_reg_operand" "")]))
3957 (use (match_operand 3 ""))]
3959 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3964 (define_expand "cstore<mode>4"
3965 [(use (match_operator 1 "ordered_comparison_operator"
3966 [(match_operand:VQHSI 2 "spu_reg_operand" "")
3967 (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3968 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3970 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3972 (define_expand "cstore<mode>4"
3973 [(use (match_operator 1 "ordered_comparison_operator"
3974 [(match_operand:DTI 2 "spu_reg_operand" "")
3975 (match_operand:DTI 3 "spu_reg_operand" "")]))
3976 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3978 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3980 (define_expand "cstore<mode>4"
3981 [(use (match_operator 1 "ordered_comparison_operator"
3982 [(match_operand:VSF 2 "spu_reg_operand" "")
3983 (match_operand:VSF 3 "spu_reg_operand" "")]))
3984 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3986 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3988 (define_expand "cstoredf4"
3989 [(use (match_operator 1 "ordered_comparison_operator"
3990 [(match_operand:DF 2 "spu_reg_operand" "")
3991 (match_operand:DF 3 "spu_reg_operand" "")]))
3992 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3994 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3999 ;; Define this first one so HAVE_conditional_move is defined.
4000 (define_insn "movcc_dummy"
4001 [(set (match_operand 0 "" "")
4002 (if_then_else (match_operand 1 "" "")
4003 (match_operand 2 "" "")
4004 (match_operand 3 "" "")))]
4008 (define_expand "mov<mode>cc"
4009 [(set (match_operand:ALL 0 "spu_reg_operand" "")
4010 (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
4011 (match_operand:ALL 2 "spu_reg_operand" "")
4012 (match_operand:ALL 3 "spu_reg_operand" "")))]
4015 spu_emit_branch_or_set(2, operands[1], operands);
4019 ;; This pattern is used when the result of a compare is not large
4020 ;; enough to use in a selb when expanding conditional moves.
4021 (define_expand "extend_compare"
4022 [(set (match_operand 0 "spu_reg_operand" "=r")
4023 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4026 emit_insn (gen_rtx_SET (operands[0],
4027 gen_rtx_UNSPEC (GET_MODE (operands[0]),
4028 gen_rtvec (1, operands[1]),
4029 UNSPEC_EXTEND_CMP)));
4033 (define_insn "extend_compare<mode>"
4034 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
4035 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4038 [(set_attr "type" "shuf")])
4043 ;; operand 0 is index
4044 ;; operand 1 is the minimum bound
4045 ;; operand 2 is the maximum bound - minimum bound + 1
4046 ;; operand 3 is CODE_LABEL for the table;
4047 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4048 (define_expand "casesi"
4049 [(match_operand:SI 0 "spu_reg_operand" "")
4050 (match_operand:SI 1 "immediate_operand" "")
4051 (match_operand:SI 2 "immediate_operand" "")
4052 (match_operand 3 "" "")
4053 (match_operand 4 "" "")]
4056 rtx table = gen_reg_rtx (SImode);
4057 rtx index = gen_reg_rtx (SImode);
4058 rtx sindex = gen_reg_rtx (SImode);
4059 rtx addr = gen_reg_rtx (Pmode);
4061 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
4063 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
4064 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
4065 emit_move_insn (addr, gen_rtx_MEM (SImode,
4066 gen_rtx_PLUS (SImode, table, sindex)));
4068 emit_insn (gen_addsi3 (addr, addr, table));
4070 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
4071 emit_jump_insn (gen_tablejump (addr, operands[3]));
4075 (define_insn "tablejump"
4076 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
4077 (use (label_ref (match_operand 1 "" "")))]
4080 [(set_attr "type" "br")])
4085 ;; Note that operand 1 is total size of args, in bytes,
4086 ;; and what the call insn wants is the number of words.
4087 (define_expand "sibcall"
4089 [(call (match_operand:QI 0 "call_operand" "")
4090 (match_operand:QI 1 "" ""))
4094 if (! call_operand (operands[0], QImode))
4095 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4098 (define_insn "_sibcall"
4100 [(call (match_operand:QI 0 "call_operand" "R,S")
4101 (match_operand:QI 1 "" "i,i"))
4103 "SIBLING_CALL_P(insn)"
4107 [(set_attr "type" "br,br")])
4109 (define_expand "sibcall_value"
4111 [(set (match_operand 0 "" "")
4112 (call (match_operand:QI 1 "call_operand" "")
4113 (match_operand:QI 2 "" "")))
4117 if (! call_operand (operands[1], QImode))
4118 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4121 (define_insn "_sibcall_value"
4123 [(set (match_operand 0 "" "")
4124 (call (match_operand:QI 1 "call_operand" "R,S")
4125 (match_operand:QI 2 "" "i,i")))
4127 "SIBLING_CALL_P(insn)"
4131 [(set_attr "type" "br,br")])
4133 ;; Note that operand 1 is total size of args, in bytes,
4134 ;; and what the call insn wants is the number of words.
4135 (define_expand "call"
4137 [(call (match_operand:QI 0 "call_operand" "")
4138 (match_operand:QI 1 "" ""))
4139 (clobber (reg:SI 0))
4140 (clobber (reg:SI 130))])]
4143 if (! call_operand (operands[0], QImode))
4144 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4147 (define_insn "_call"
4149 [(call (match_operand:QI 0 "call_operand" "R,S,T")
4150 (match_operand:QI 1 "" "i,i,i"))
4151 (clobber (reg:SI 0))
4152 (clobber (reg:SI 130))])]
4158 [(set_attr "type" "br")])
4160 (define_expand "call_value"
4162 [(set (match_operand 0 "" "")
4163 (call (match_operand:QI 1 "call_operand" "")
4164 (match_operand:QI 2 "" "")))
4165 (clobber (reg:SI 0))
4166 (clobber (reg:SI 130))])]
4169 if (! call_operand (operands[1], QImode))
4170 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4173 (define_insn "_call_value"
4175 [(set (match_operand 0 "" "")
4176 (call (match_operand:QI 1 "call_operand" "R,S,T")
4177 (match_operand:QI 2 "" "i,i,i")))
4178 (clobber (reg:SI 0))
4179 (clobber (reg:SI 130))])]
4185 [(set_attr "type" "br")])
4187 (define_expand "untyped_call"
4188 [(parallel [(call (match_operand 0 "" "")
4190 (match_operand 1 "" "")
4191 (match_operand 2 "" "")])]
4195 rtx reg = gen_rtx_REG (TImode, 3);
4197 /* We need to use call_value so the return value registers don't get
4199 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4201 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4203 rtx set = XVECEXP (operands[2], 0, i);
4204 emit_move_insn (SET_DEST (set), SET_SRC (set));
4207 /* The optimizer does not know that the call sets the function value
4208 registers we stored in the result block. We avoid problems by
4209 claiming that all hard registers are used and clobbered at this
4211 emit_insn (gen_blockage ());
4217 ;; Patterns used for splitting and combining.
4220 ;; Function prologue and epilogue.
4222 (define_expand "prologue"
4225 { spu_expand_prologue (); DONE; })
4227 ;; "blockage" is only emitted in epilogue. This is what it took to
4228 ;; make "basic block reordering" work with the insns sequence
4229 ;; generated by the spu_expand_epilogue (taken from mips.md)
4231 (define_insn "blockage"
4232 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
4235 [(set_attr "type" "convert")
4236 (set_attr "length" "0")])
4238 (define_expand "epilogue"
4241 { spu_expand_epilogue (false); DONE; })
4243 (define_expand "sibcall_epilogue"
4246 { spu_expand_epilogue (true); DONE; })
4249 ;; stack manipulations
4251 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4252 ;; We move the back-chain and decrement the stack pointer.
4253 (define_expand "allocate_stack"
4254 [(set (match_operand 0 "spu_reg_operand" "")
4255 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4257 (minus (reg 1) (match_dup 1)))]
4259 "spu_allocate_stack (operands[0], operands[1]); DONE;")
4261 ;; These patterns say how to save and restore the stack pointer. We need not
4262 ;; save the stack pointer at function level since we are careful to preserve
4266 ;; At block level the stack pointer is saved and restored, so that the
4267 ;; stack space allocated within a block is deallocated when leaving
4268 ;; block scope. By default, according to the SPU ABI, the stack
4269 ;; pointer and available stack size are saved in a register. Upon
4270 ;; restoration, the stack pointer is simply copied back, and the
4271 ;; current available stack size is calculated against the restored
4274 ;; For nonlocal gotos, we must save the stack pointer and its
4275 ;; backchain and restore both. Note that in the nonlocal case, the
4276 ;; save area is a memory location.
4278 (define_expand "save_stack_function"
4279 [(match_operand 0 "general_operand" "")
4280 (match_operand 1 "general_operand" "")]
4284 (define_expand "restore_stack_function"
4285 [(match_operand 0 "general_operand" "")
4286 (match_operand 1 "general_operand" "")]
4290 (define_expand "restore_stack_block"
4291 [(match_operand 0 "spu_reg_operand" "")
4292 (match_operand 1 "memory_operand" "")]
4296 spu_restore_stack_block (operands[0], operands[1]);
4300 (define_expand "save_stack_nonlocal"
4301 [(match_operand 0 "memory_operand" "")
4302 (match_operand 1 "spu_reg_operand" "")]
4306 rtx temp = gen_reg_rtx (Pmode);
4308 /* Copy the backchain to the first word, sp to the second. We need to
4309 save the back chain because __builtin_apply appears to clobber it. */
4310 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4311 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4312 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4316 (define_expand "restore_stack_nonlocal"
4317 [(match_operand 0 "spu_reg_operand" "")
4318 (match_operand 1 "memory_operand" "")]
4322 spu_restore_stack_nonlocal(operands[0], operands[1]);
4329 ;; Vector initialization
4330 (define_expand "vec_init<mode><inner_l>"
4331 [(match_operand:V 0 "register_operand" "")
4332 (match_operand 1 "" "")]
4335 spu_expand_vector_init (operands[0], operands[1]);
4339 (define_expand "vec_set<mode>"
4340 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4341 (set (match_dup:TI 3)
4342 (unspec:TI [(match_dup:SI 4)
4344 (match_dup:SI 6)] UNSPEC_CPAT))
4345 (set (match_operand:V 0 "spu_reg_operand" "")
4346 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4348 (match_dup:TI 3)] UNSPEC_SHUFB))]
4351 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4352 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4353 operands[3] = gen_reg_rtx (TImode);
4354 operands[4] = stack_pointer_rtx;
4355 operands[5] = offset;
4356 operands[6] = GEN_INT (size);
4359 (define_expand "vec_extract<mode><inner_l>"
4360 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4361 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4362 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4365 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4367 emit_insn (gen_spu_convert (operands[0], operands[1]));
4372 (define_insn "_vec_extract<mode>"
4373 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4374 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4375 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4377 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4378 [(set_attr "type" "shuf")])
4380 (define_insn "_vec_extractv8hi_ze"
4381 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4382 (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4383 (parallel [(const_int 0)]))))]
4385 "rotqmbyi\t%0,%1,-2"
4386 [(set_attr "type" "shuf")])
4391 (define_expand "shufb"
4392 [(set (match_operand 0 "spu_reg_operand" "")
4393 (unspec [(match_operand 1 "spu_reg_operand" "")
4394 (match_operand 2 "spu_reg_operand" "")
4395 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4398 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4399 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4404 (define_insn "_shufb"
4405 [(set (match_operand 0 "spu_reg_operand" "=r")
4406 (unspec [(match_operand 1 "spu_reg_operand" "r")
4407 (match_operand 2 "spu_reg_operand" "r")
4408 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4410 "shufb\t%0,%1,%2,%3"
4411 [(set_attr "type" "shuf")])
4413 ; The semantics of vec_permv16qi are nearly identical to those of the SPU
4414 ; shufb instruction, except that we need to reduce the selector modulo 32.
4415 (define_expand "vec_permv16qi"
4416 [(set (match_dup 4) (and:V16QI (match_operand:V16QI 3 "spu_reg_operand" "")
4418 (set (match_operand:V16QI 0 "spu_reg_operand" "")
4420 [(match_operand:V16QI 1 "spu_reg_operand" "")
4421 (match_operand:V16QI 2 "spu_reg_operand" "")
4426 operands[4] = gen_reg_rtx (V16QImode);
4427 operands[5] = gen_lowpart (TImode, operands[4]);
4428 operands[6] = spu_const (V16QImode, 31);
4432 [(unspec_volatile [(const_int 0)] UNSPECV_NOP)]
4435 [(set_attr "type" "nop")])
4438 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPECV_NOP)]
4441 [(set_attr "type" "nop")])
4444 [(unspec_volatile [(const_int 0)] UNSPECV_LNOP)]
4447 [(set_attr "type" "lnop")])
4449 ;; The operand is so we know why we generated this hbrp.
4450 ;; We clobber mem to make sure it isn't moved over any
4451 ;; loads, stores or calls while scheduling.
4452 (define_insn "iprefetch"
4453 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4454 (clobber (mem:BLK (scratch)))]
4457 [(set_attr "type" "iprefetch")])
4459 ;; A non-volatile version so it gets scheduled
4460 (define_insn "nopn_nv"
4461 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4464 [(set_attr "type" "nop")])
4468 (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4469 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4470 (unspec [(const_int 0)] UNSPEC_HBR)]
4476 [(set_attr "type" "hbr")])
4479 [(unspec_volatile [(const_int 0)] UNSPECV_SYNC)
4480 (clobber (mem:BLK (scratch)))]
4483 [(set_attr "type" "br")])
4485 (define_insn "syncc"
4486 [(unspec_volatile [(const_int 1)] UNSPECV_SYNC)
4487 (clobber (mem:BLK (scratch)))]
4490 [(set_attr "type" "br")])
4492 (define_insn "dsync"
4493 [(unspec_volatile [(const_int 2)] UNSPECV_SYNC)
4494 (clobber (mem:BLK (scratch)))]
4497 [(set_attr "type" "br")])
4501 ;; Define the subtract-one-and-jump insns so loop.c
4502 ;; knows what to generate.
4503 (define_expand "doloop_end"
4504 [(use (match_operand 0 "" "")) ; loop pseudo
4505 (use (match_operand 1 "" ""))] ; label
4509 /* Currently SMS relies on the do-loop pattern to recognize loops
4510 where (1) the control part comprises of all insns defining and/or
4511 using a certain 'count' register and (2) the loop count can be
4512 adjusted by modifying this register prior to the loop.
4513 . ??? The possible introduction of a new block to initialize the
4514 new IV can potentially effects branch optimizations. */
4515 if (optimize > 0 && flag_modulo_sched)
4521 if (GET_MODE (operands[0]) != SImode)
4525 emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4526 bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4527 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4528 emit_jump_insn (gen_rtx_SET (pc_rtx,
4529 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4537 ;; convert between any two modes, avoiding any GCC assumptions
4538 (define_expand "spu_convert"
4539 [(set (match_operand 0 "spu_reg_operand" "")
4540 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4543 rtx c = gen__spu_convert (operands[0], operands[1]);
4544 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4549 (define_insn_and_split "_spu_convert"
4550 [(set (match_operand 0 "spu_reg_operand" "=r")
4551 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4557 spu_split_convert (operands);
4560 [(set_attr "type" "convert")
4561 (set_attr "length" "0")])
4565 (include "spu-builtins.md")
4568 (define_expand "smaxv4sf3"
4569 [(set (match_operand:V4SF 0 "register_operand" "=r")
4570 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4571 (match_operand:V4SF 2 "register_operand" "r")))]
4575 rtx mask = gen_reg_rtx (V4SImode);
4577 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4578 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4582 (define_expand "sminv4sf3"
4583 [(set (match_operand:V4SF 0 "register_operand" "=r")
4584 (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4585 (match_operand:V4SF 2 "register_operand" "r")))]
4589 rtx mask = gen_reg_rtx (V4SImode);
4591 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4592 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4596 (define_expand "smaxv2df3"
4597 [(set (match_operand:V2DF 0 "register_operand" "=r")
4598 (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4599 (match_operand:V2DF 2 "register_operand" "r")))]
4603 rtx mask = gen_reg_rtx (V2DImode);
4604 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4605 emit_insn (gen_selb (operands[0], operands[2], operands[1],
4606 spu_gen_subreg (V4SImode, mask)));
4610 (define_expand "sminv2df3"
4611 [(set (match_operand:V2DF 0 "register_operand" "=r")
4612 (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4613 (match_operand:V2DF 2 "register_operand" "r")))]
4617 rtx mask = gen_reg_rtx (V2DImode);
4618 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4619 emit_insn (gen_selb (operands[0], operands[1], operands[2],
4620 spu_gen_subreg (V4SImode, mask)));
4624 (define_insn "vec_widen_smult_odd_v8hi"
4625 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
4629 (match_operand:V8HI 1 "spu_reg_operand" "r,r")
4630 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
4633 (match_operand:V8HI 2 "spu_arith_operand" "r,B")
4634 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
4639 [(set_attr "type" "fp7")])
4641 (define_insn "vec_widen_umult_odd_v8hi"
4642 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
4646 (match_operand:V8HI 1 "spu_reg_operand" "r,r")
4647 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
4650 (match_operand:V8HI 2 "spu_arith_operand" "r,B")
4651 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
4656 [(set_attr "type" "fp7")])
4658 (define_insn "vec_widen_smult_even_v8hi"
4659 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4663 (match_operand:V8HI 1 "spu_reg_operand" "r")
4664 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
4667 (match_operand:V8HI 2 "spu_reg_operand" "r")
4668 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
4671 [(set_attr "type" "fp7")])
4673 (define_insn "vec_widen_umult_even_v8hi"
4674 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4678 (match_operand:V8HI 1 "spu_reg_operand" "r")
4679 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
4682 (match_operand:V8HI 2 "spu_reg_operand" "r")
4683 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
4686 [(set_attr "type" "fp7")])
4688 (define_expand "vec_widen_umult_hi_v8hi"
4689 [(set (match_operand:V4SI 0 "register_operand" "=r")
4693 (match_operand:V8HI 1 "register_operand" "r")
4694 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4697 (match_operand:V8HI 2 "register_operand" "r")
4698 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4702 rtx ve = gen_reg_rtx (V4SImode);
4703 rtx vo = gen_reg_rtx (V4SImode);
4704 rtx mask = gen_reg_rtx (TImode);
4705 unsigned char arr[16] = {
4706 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4707 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4709 emit_move_insn (mask, array_to_constant (TImode, arr));
4710 emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
4711 emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
4712 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4716 (define_expand "vec_widen_umult_lo_v8hi"
4717 [(set (match_operand:V4SI 0 "register_operand" "=r")
4721 (match_operand:V8HI 1 "register_operand" "r")
4722 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4725 (match_operand:V8HI 2 "register_operand" "r")
4726 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4730 rtx ve = gen_reg_rtx (V4SImode);
4731 rtx vo = gen_reg_rtx (V4SImode);
4732 rtx mask = gen_reg_rtx (TImode);
4733 unsigned char arr[16] = {
4734 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4735 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4737 emit_move_insn (mask, array_to_constant (TImode, arr));
4738 emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
4739 emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
4740 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4744 (define_expand "vec_widen_smult_hi_v8hi"
4745 [(set (match_operand:V4SI 0 "register_operand" "=r")
4749 (match_operand:V8HI 1 "register_operand" "r")
4750 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4753 (match_operand:V8HI 2 "register_operand" "r")
4754 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4758 rtx ve = gen_reg_rtx (V4SImode);
4759 rtx vo = gen_reg_rtx (V4SImode);
4760 rtx mask = gen_reg_rtx (TImode);
4761 unsigned char arr[16] = {
4762 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4763 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4765 emit_move_insn (mask, array_to_constant (TImode, arr));
4766 emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
4767 emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
4768 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4772 (define_expand "vec_widen_smult_lo_v8hi"
4773 [(set (match_operand:V4SI 0 "register_operand" "=r")
4777 (match_operand:V8HI 1 "register_operand" "r")
4778 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4781 (match_operand:V8HI 2 "register_operand" "r")
4782 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4786 rtx ve = gen_reg_rtx (V4SImode);
4787 rtx vo = gen_reg_rtx (V4SImode);
4788 rtx mask = gen_reg_rtx (TImode);
4789 unsigned char arr[16] = {
4790 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4791 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4793 emit_move_insn (mask, array_to_constant (TImode, arr));
4794 emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
4795 emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
4796 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4800 (define_expand "vec_realign_load_<mode>"
4801 [(set (match_operand:ALL 0 "register_operand" "=r")
4802 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4803 (match_operand:ALL 2 "register_operand" "r")
4804 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4808 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4812 (define_expand "spu_lvsr"
4813 [(set (match_operand:V16QI 0 "register_operand" "")
4814 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4819 rtx offset = gen_reg_rtx (V8HImode);
4820 rtx addr_bits = gen_reg_rtx (SImode);
4821 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4822 rtx splatqi = gen_reg_rtx (TImode);
4823 rtx result = gen_reg_rtx (V8HImode);
4824 unsigned char arr[16] = {
4825 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4826 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4827 unsigned char arr2[16] = {
4828 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4829 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4831 emit_move_insn (offset, array_to_constant (V8HImode, arr));
4832 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4834 gcc_assert (GET_CODE (operands[1]) == MEM);
4835 addr = force_reg (Pmode, XEXP (operands[1], 0));
4836 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4837 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4839 /* offset - (addr & 0xF)
4840 It is safe to use a single sfh, because each byte of offset is > 15 and
4841 each byte of addr is <= 15. */
4842 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4844 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4845 emit_move_insn (operands[0], result);
4850 (define_expand "vec_unpacku_hi_v8hi"
4851 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4854 (match_operand:V8HI 1 "spu_reg_operand" "r")
4855 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4858 rtx mask = gen_reg_rtx (TImode);
4859 unsigned char arr[16] = {
4860 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4861 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4863 emit_move_insn (mask, array_to_constant (TImode, arr));
4864 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4869 (define_expand "vec_unpacku_lo_v8hi"
4870 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4873 (match_operand:V8HI 1 "spu_reg_operand" "r")
4874 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4877 rtx mask = gen_reg_rtx (TImode);
4878 unsigned char arr[16] = {
4879 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4880 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4882 emit_move_insn (mask, array_to_constant (TImode, arr));
4883 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4888 (define_expand "vec_unpacks_hi_v8hi"
4889 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4892 (match_operand:V8HI 1 "spu_reg_operand" "r")
4893 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4896 rtx tmp1 = gen_reg_rtx (V8HImode);
4897 rtx tmp2 = gen_reg_rtx (V4SImode);
4898 rtx mask = gen_reg_rtx (TImode);
4899 unsigned char arr[16] = {
4900 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4901 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4903 emit_move_insn (mask, array_to_constant (TImode, arr));
4904 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4905 emit_insn (gen_spu_xshw (tmp2, tmp1));
4906 emit_move_insn (operands[0], tmp2);
4911 (define_expand "vec_unpacks_lo_v8hi"
4912 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4915 (match_operand:V8HI 1 "spu_reg_operand" "r")
4916 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4919 rtx tmp1 = gen_reg_rtx (V8HImode);
4920 rtx tmp2 = gen_reg_rtx (V4SImode);
4921 rtx mask = gen_reg_rtx (TImode);
4922 unsigned char arr[16] = {
4923 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4924 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4926 emit_move_insn (mask, array_to_constant (TImode, arr));
4927 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4928 emit_insn (gen_spu_xshw (tmp2, tmp1));
4929 emit_move_insn (operands[0], tmp2);
4934 (define_expand "vec_unpacku_hi_v16qi"
4935 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4938 (match_operand:V16QI 1 "spu_reg_operand" "r")
4939 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4940 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4943 rtx mask = gen_reg_rtx (TImode);
4944 unsigned char arr[16] = {
4945 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4946 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4948 emit_move_insn (mask, array_to_constant (TImode, arr));
4949 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4954 (define_expand "vec_unpacku_lo_v16qi"
4955 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4958 (match_operand:V16QI 1 "spu_reg_operand" "r")
4959 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4960 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4963 rtx mask = gen_reg_rtx (TImode);
4964 unsigned char arr[16] = {
4965 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4966 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4968 emit_move_insn (mask, array_to_constant (TImode, arr));
4969 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4974 (define_expand "vec_unpacks_hi_v16qi"
4975 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4978 (match_operand:V16QI 1 "spu_reg_operand" "r")
4979 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4980 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4983 rtx tmp1 = gen_reg_rtx (V16QImode);
4984 rtx tmp2 = gen_reg_rtx (V8HImode);
4985 rtx mask = gen_reg_rtx (TImode);
4986 unsigned char arr[16] = {
4987 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4988 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4990 emit_move_insn (mask, array_to_constant (TImode, arr));
4991 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4992 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4993 emit_move_insn (operands[0], tmp2);
4998 (define_expand "vec_unpacks_lo_v16qi"
4999 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5002 (match_operand:V16QI 1 "spu_reg_operand" "r")
5003 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5004 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
5007 rtx tmp1 = gen_reg_rtx (V16QImode);
5008 rtx tmp2 = gen_reg_rtx (V8HImode);
5009 rtx mask = gen_reg_rtx (TImode);
5010 unsigned char arr[16] = {
5011 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
5012 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
5014 emit_move_insn (mask, array_to_constant (TImode, arr));
5015 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
5016 emit_insn (gen_spu_xsbh (tmp2, tmp1));
5017 emit_move_insn (operands[0], tmp2);
5023 (define_expand "vec_pack_trunc_v8hi"
5024 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5026 (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5027 (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5031 rtx mask = gen_reg_rtx (TImode);
5032 unsigned char arr[16] = {
5033 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5034 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5036 emit_move_insn (mask, array_to_constant (TImode, arr));
5037 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5042 (define_expand "vec_pack_trunc_v4si"
5043 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5045 (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5046 (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5050 rtx mask = gen_reg_rtx (TImode);
5051 unsigned char arr[16] = {
5052 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5053 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5055 emit_move_insn (mask, array_to_constant (TImode, arr));
5056 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5061 (define_insn "stack_protect_set"
5062 [(set (match_operand:SI 0 "memory_operand" "=m")
5063 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5064 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5066 "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5067 [(set_attr "length" "12")
5068 (set_attr "type" "multi1")]
5071 (define_expand "stack_protect_test"
5072 [(match_operand 0 "memory_operand" "")
5073 (match_operand 1 "memory_operand" "")
5074 (match_operand 2 "" "")]
5080 compare_result = gen_reg_rtx (SImode);
5082 emit_insn (gen_stack_protect_test_si (compare_result,
5086 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5088 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5090 emit_jump_insn (gen_rtx_SET (pc_rtx,
5091 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5097 (define_insn "stack_protect_test_si"
5098 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5099 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5100 (match_operand:SI 2 "memory_operand" "m")]
5102 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5104 "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5105 [(set_attr "length" "16")
5106 (set_attr "type" "multi1")]
5111 ; SPU execution is always single-threaded, so there is no need for real
5112 ; atomic operations. We provide the atomic primitives anyway so that
5113 ; code expecting the builtins to be present (like libgfortran) will work.
5115 ;; Types that we should provide atomic instructions for.
5116 (define_mode_iterator AINT [QI HI SI DI TI])
5118 (define_code_iterator ATOMIC [plus minus ior xor and mult])
5119 (define_code_attr atomic_name
5120 [(plus "add") (minus "sub")
5121 (ior "or") (xor "xor") (and "and") (mult "nand")])
5122 (define_code_attr atomic_pred
5123 [(plus "spu_arith_operand") (minus "spu_reg_operand")
5124 (ior "spu_logical_operand") (xor "spu_logical_operand")
5125 (and "spu_logical_operand") (mult "spu_logical_operand")])
5127 (define_expand "atomic_load<mode>"
5128 [(set (match_operand:AINT 0 "spu_reg_operand" "") ;; output
5129 (match_operand:AINT 1 "memory_operand" "")) ;; memory
5130 (use (match_operand:SI 2 "const_int_operand" ""))] ;; model
5133 if (MEM_ADDR_SPACE (operands[1]))
5136 emit_move_insn (operands[0], operands[1]);
5140 (define_expand "atomic_store<mode>"
5141 [(set (match_operand:AINT 0 "memory_operand" "") ;; memory
5142 (match_operand:AINT 1 "spu_reg_operand" "")) ;; input
5143 (use (match_operand:SI 2 "const_int_operand" ""))] ;; model
5146 if (MEM_ADDR_SPACE (operands[0]))
5149 emit_move_insn (operands[0], operands[1]);
5153 (define_expand "atomic_compare_and_swap<mode>"
5154 [(match_operand:SI 0 "spu_reg_operand" "") ;; bool out
5155 (match_operand:AINT 1 "spu_reg_operand" "") ;; val out
5156 (match_operand:AINT 2 "memory_operand" "") ;; memory
5157 (match_operand:AINT 3 "spu_nonmem_operand" "") ;; expected
5158 (match_operand:AINT 4 "spu_nonmem_operand" "") ;; desired
5159 (match_operand:SI 5 "const_int_operand" "") ;; is_weak
5160 (match_operand:SI 6 "const_int_operand" "") ;; model succ
5161 (match_operand:SI 7 "const_int_operand" "")] ;; model fail
5164 rtx boolval, retval, label;
5166 if (MEM_ADDR_SPACE (operands[2]))
5169 boolval = gen_reg_rtx (SImode);
5170 retval = gen_reg_rtx (<MODE>mode);
5171 label = gen_label_rtx ();
5173 emit_move_insn (retval, operands[2]);
5174 emit_move_insn (boolval, const0_rtx);
5176 emit_cmp_and_jump_insns (retval, operands[3], NE, NULL_RTX,
5177 <MODE>mode, 1, label);
5179 emit_move_insn (operands[2], operands[4]);
5180 emit_move_insn (boolval, const1_rtx);
5184 emit_move_insn (operands[0], boolval);
5185 emit_move_insn (operands[1], retval);
5189 (define_expand "atomic_exchange<mode>"
5190 [(match_operand:AINT 0 "spu_reg_operand" "") ;; output
5191 (match_operand:AINT 1 "memory_operand" "") ;; memory
5192 (match_operand:AINT 2 "spu_nonmem_operand" "") ;; input
5193 (match_operand:SI 3 "const_int_operand" "")] ;; model
5198 if (MEM_ADDR_SPACE (operands[1]))
5201 retval = gen_reg_rtx (<MODE>mode);
5203 emit_move_insn (retval, operands[1]);
5204 emit_move_insn (operands[1], operands[2]);
5205 emit_move_insn (operands[0], retval);
5209 (define_expand "atomic_<atomic_name><mode>"
5211 (match_operand:AINT 0 "memory_operand" "") ;; memory
5212 (match_operand:AINT 1 "<atomic_pred>" "")) ;; operand
5213 (match_operand:SI 2 "const_int_operand" "")] ;; model
5216 if (MEM_ADDR_SPACE (operands[0]))
5219 spu_expand_atomic_op (<CODE>, operands[0], operands[1],
5220 NULL_RTX, NULL_RTX);
5224 (define_expand "atomic_fetch_<atomic_name><mode>"
5225 [(match_operand:AINT 0 "spu_reg_operand" "") ;; output
5227 (match_operand:AINT 1 "memory_operand" "") ;; memory
5228 (match_operand:AINT 2 "<atomic_pred>" "")) ;; operand
5229 (match_operand:SI 3 "const_int_operand" "")] ;; model
5232 if (MEM_ADDR_SPACE (operands[1]))
5235 spu_expand_atomic_op (<CODE>, operands[1], operands[2],
5236 operands[0], NULL_RTX);
5240 (define_expand "atomic_<atomic_name>_fetch<mode>"
5241 [(match_operand:AINT 0 "spu_reg_operand" "") ;; output
5243 (match_operand:AINT 1 "memory_operand" "") ;; memory
5244 (match_operand:AINT 2 "<atomic_pred>" "")) ;; operand
5245 (match_operand:SI 3 "const_int_operand" "")] ;; model
5248 if (MEM_ADDR_SPACE (operands[1]))
5251 spu_expand_atomic_op (<CODE>, operands[1], operands[2],
5252 NULL_RTX, operands[0]);