1 ;; Copyright (C) 2006-2016 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 (define_mode_attr vmult [(V16QI "1")
265 (define_mode_attr voff [(V16QI "13")
275 (define_expand "mov<mode>"
276 [(set (match_operand:ALL 0 "nonimmediate_operand" "")
277 (match_operand:ALL 1 "general_operand" ""))]
280 if (spu_expand_mov(operands, <MODE>mode))
285 [(set (match_operand 0 "spu_reg_operand")
286 (match_operand 1 "immediate_operand"))]
290 (high (match_dup 1)))
292 (lo_sum (match_dup 0)
295 if (spu_split_immediate (operands))
301 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
302 (match_operand:SI 1 "immediate_operand" "s"))
307 ;; Whenever a function generates the 'pic' pattern above we need to
308 ;; load the pic_offset_table register.
309 ;; GCC doesn't deal well with labels in the middle of a block so we
310 ;; hardcode the offsets in the asm here.
311 (define_insn "load_pic_offset"
312 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
313 (unspec:SI [(const_int 0)] 0))
314 (set (match_operand:SI 1 "spu_reg_operand" "=r")
315 (unspec:SI [(const_int 0)] 0))]
317 "ila\t%1,.+8\;brsl\t%0,4"
318 [(set_attr "length" "8")
319 (set_attr "type" "multi0")])
324 (define_insn "_mov<mode>"
325 [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
326 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
327 "register_operand(operands[0], <MODE>mode)
328 || register_operand(operands[1], <MODE>mode)"
336 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
338 (define_insn "low_<mode>"
339 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
340 (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
341 (match_operand:VSI 2 "immediate_operand" "i")))]
345 (define_insn "_movdi"
346 [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
347 (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
348 "register_operand(operands[0], DImode)
349 || register_operand(operands[1], DImode)"
357 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
359 (define_insn "_movti"
360 [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
361 (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
362 "register_operand(operands[0], TImode)
363 || register_operand(operands[1], TImode)"
371 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
374 [(set (match_operand 0 "spu_reg_operand")
375 (match_operand 1 "memory_operand"))]
376 "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
377 && GET_MODE(operands[0]) == GET_MODE(operands[1])
378 && !reload_in_progress && !reload_completed"
381 { if (spu_split_load(operands))
386 [(set (match_operand 0 "memory_operand")
387 (match_operand 1 "spu_reg_operand"))]
388 "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
389 && GET_MODE(operands[0]) == GET_MODE(operands[1])
390 && !reload_in_progress && !reload_completed"
393 { if (spu_split_store(operands))
396 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
398 (define_expand "cpat"
399 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
400 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
401 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
402 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
405 rtx x = gen_cpat_const (operands);
408 emit_move_insn (operands[0], x);
414 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
415 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
416 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
417 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
422 [(set_attr "type" "shuf")])
425 [(set (match_operand:TI 0 "spu_reg_operand")
426 (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
427 (match_operand:SI 2 "immediate_operand")
428 (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
430 [(set (match_dup:TI 0)
433 operands[4] = gen_cpat_const (operands);
440 (define_insn "extendqihi2"
441 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
442 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
446 (define_insn "extendhisi2"
447 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
448 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
452 (define_expand "extendsidi2"
453 [(set (match_dup:DI 2)
454 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
455 (set (match_operand:DI 0 "spu_reg_operand" "")
456 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
457 (parallel [(const_int 1)]))))]
460 operands[2] = gen_reg_rtx (DImode);
461 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
465 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
468 (match_operand:V2SI 1 "spu_reg_operand" "r")
469 (parallel [(const_int 1) ]))))]
473 ;; By splitting this late we don't allow much opportunity for sharing of
474 ;; constants. That's ok because this should really be optimized away.
475 (define_insn_and_split "extend<mode>ti2"
476 [(set (match_operand:TI 0 "register_operand" "")
477 (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
481 [(set (match_dup:TI 0)
482 (sign_extend:TI (match_dup:QHSDI 1)))]
484 spu_expand_sign_extend(operands);
491 (define_insn "zero_extendqihi2"
492 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
493 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
495 "andi\t%0,%1,0x00ff")
497 (define_insn "zero_extendqisi2"
498 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
499 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
501 "andi\t%0,%1,0x00ff")
503 (define_expand "zero_extendhisi2"
504 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
505 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
506 (clobber (match_scratch:SI 2 "=&r"))]
509 rtx mask = gen_reg_rtx (SImode);
510 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
511 emit_move_insn (mask, GEN_INT (0xffff));
512 emit_insn (gen_andsi3(operands[0], op1, mask));
516 (define_insn "zero_extendsidi2"
517 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
518 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
521 [(set_attr "type" "shuf")])
523 (define_insn "zero_extendqiti2"
524 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
525 (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
527 "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
528 [(set_attr "type" "multi0")
529 (set_attr "length" "8")])
531 (define_insn "zero_extendhiti2"
532 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
533 (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
535 "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
536 [(set_attr "type" "multi1")
537 (set_attr "length" "8")])
539 (define_insn "zero_extendsiti2"
540 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
541 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
543 "rotqmbyi\t%0,%1,-12"
544 [(set_attr "type" "shuf")])
546 (define_insn "zero_extendditi2"
547 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
548 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
551 [(set_attr "type" "shuf")])
556 (define_insn "truncdiqi2"
557 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
558 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
561 [(set_attr "type" "shuf")])
563 (define_insn "truncdihi2"
564 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
565 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
568 [(set_attr "type" "shuf")])
570 (define_insn "truncdisi2"
571 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
572 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
575 [(set_attr "type" "shuf")])
577 (define_insn "trunctiqi2"
578 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
579 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
582 [(set_attr "type" "shuf")])
584 (define_insn "trunctihi2"
585 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
586 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
589 [(set_attr "type" "shuf")])
591 (define_insn "trunctisi2"
592 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
593 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
596 [(set_attr "type" "shuf")])
598 (define_insn "trunctidi2"
599 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
600 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
603 [(set_attr "type" "shuf")])
608 (define_insn "float<mode><i2f>2"
609 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
610 (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
613 [(set_attr "type" "fp7")])
615 (define_insn "fix_trunc<mode><f2i>2"
616 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
617 (fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
620 [(set_attr "type" "fp7")])
622 (define_insn "floatuns<mode><i2f>2"
623 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
624 (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
627 [(set_attr "type" "fp7")])
629 (define_insn "fixuns_trunc<mode><f2i>2"
630 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
631 (unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
634 [(set_attr "type" "fp7")])
636 (define_insn "float<mode><i2f>2_mul"
637 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
638 (mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
639 (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
642 [(set_attr "type" "fp7")])
644 (define_insn "float<mode><i2f>2_div"
645 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
646 (div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
647 (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
650 [(set_attr "type" "fp7")])
653 (define_insn "fix_trunc<mode><f2i>2_mul"
654 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
655 (fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
656 (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
659 [(set_attr "type" "fp7")])
661 (define_insn "floatuns<mode><i2f>2_mul"
662 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
663 (mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
664 (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
667 [(set_attr "type" "fp7")])
669 (define_insn "floatuns<mode><i2f>2_div"
670 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
671 (div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
672 (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
675 [(set_attr "type" "fp7")])
677 (define_insn "fixuns_trunc<mode><f2i>2_mul"
678 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
679 (unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
680 (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
683 [(set_attr "type" "fp7")])
685 (define_insn "extendsfdf2"
686 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
687 (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
688 UNSPEC_FLOAT_EXTEND))]
691 [(set_attr "type" "fpd")])
693 (define_insn "truncdfsf2"
694 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
695 (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
696 UNSPEC_FLOAT_TRUNCATE))]
699 [(set_attr "type" "fpd")])
701 (define_expand "floatdisf2"
702 [(set (match_operand:SF 0 "register_operand" "")
703 (float:SF (match_operand:DI 1 "register_operand" "")))]
706 rtx c0 = gen_reg_rtx (SImode);
707 rtx r0 = gen_reg_rtx (DImode);
708 rtx r1 = gen_reg_rtx (SFmode);
709 rtx r2 = gen_reg_rtx (SImode);
710 rtx setneg = gen_reg_rtx (SImode);
711 rtx isneg = gen_reg_rtx (SImode);
712 rtx neg = gen_reg_rtx (DImode);
713 rtx mask = gen_reg_rtx (DImode);
715 emit_move_insn (c0, GEN_INT (-0x80000000ll));
717 emit_insn (gen_negdi2 (neg, operands[1]));
718 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
719 emit_insn (gen_extend_compare (mask, isneg));
720 emit_insn (gen_selb (r0, neg, operands[1], mask));
721 emit_insn (gen_andc_si (setneg, c0, isneg));
723 emit_insn (gen_floatunsdisf2 (r1, r0));
725 emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
726 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
730 (define_insn_and_split "floatunsdisf2"
731 [(set (match_operand:SF 0 "register_operand" "=r")
732 (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))
733 (clobber (match_scratch:SF 2 "=r"))
734 (clobber (match_scratch:SF 3 "=r"))
735 (clobber (match_scratch:SF 4 "=r"))]
739 [(set (match_dup:SF 0)
740 (unsigned_float:SF (match_dup:DI 1)))]
742 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
743 rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
744 rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
745 rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
747 REAL_VALUE_TYPE scale;
748 real_2expN (&scale, 32, SFmode);
750 emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
751 emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
753 emit_move_insn (operands[4],
754 const_double_from_real_value (scale, SFmode));
755 emit_insn (gen_fmasf4 (operands[0],
756 operands[2], operands[4], operands[3]));
760 (define_expand "floattisf2"
761 [(set (match_operand:SF 0 "register_operand" "")
762 (float:SF (match_operand:TI 1 "register_operand" "")))]
765 rtx c0 = gen_reg_rtx (SImode);
766 rtx r0 = gen_reg_rtx (TImode);
767 rtx r1 = gen_reg_rtx (SFmode);
768 rtx r2 = gen_reg_rtx (SImode);
769 rtx setneg = gen_reg_rtx (SImode);
770 rtx isneg = gen_reg_rtx (SImode);
771 rtx neg = gen_reg_rtx (TImode);
772 rtx mask = gen_reg_rtx (TImode);
774 emit_move_insn (c0, GEN_INT (-0x80000000ll));
776 emit_insn (gen_negti2 (neg, operands[1]));
777 emit_insn (gen_cgt_ti_m1 (isneg, operands[1]));
778 emit_insn (gen_extend_compare (mask, isneg));
779 emit_insn (gen_selb (r0, neg, operands[1], mask));
780 emit_insn (gen_andc_si (setneg, c0, isneg));
782 emit_insn (gen_floatunstisf2 (r1, r0));
784 emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
785 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
789 (define_insn_and_split "floatunstisf2"
790 [(set (match_operand:SF 0 "register_operand" "=r")
791 (unsigned_float:SF (match_operand:TI 1 "register_operand" "r")))
792 (clobber (match_scratch:SF 2 "=r"))
793 (clobber (match_scratch:SF 3 "=r"))
794 (clobber (match_scratch:SF 4 "=r"))]
798 [(set (match_dup:SF 0)
799 (unsigned_float:SF (match_dup:TI 1)))]
801 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
802 rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
803 rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
804 rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
806 REAL_VALUE_TYPE scale;
807 real_2expN (&scale, 32, SFmode);
809 emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
810 emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
812 emit_move_insn (operands[4],
813 const_double_from_real_value (scale, SFmode));
814 emit_insn (gen_fmasf4 (operands[2],
815 operands[2], operands[4], operands[3]));
817 emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
818 emit_insn (gen_fmasf4 (operands[2],
819 operands[2], operands[4], operands[3]));
821 emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
822 emit_insn (gen_fmasf4 (operands[0],
823 operands[2], operands[4], operands[3]));
827 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
828 (define_expand "floatsidf2"
829 [(set (match_operand:DF 0 "register_operand" "")
830 (float:DF (match_operand:SI 1 "register_operand" "")))]
833 rtx c0 = gen_reg_rtx (SImode);
834 rtx c1 = gen_reg_rtx (DFmode);
835 rtx r0 = gen_reg_rtx (SImode);
836 rtx r1 = gen_reg_rtx (DFmode);
838 emit_move_insn (c0, GEN_INT (-0x80000000ll));
839 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
840 emit_insn (gen_xorsi3 (r0, operands[1], c0));
841 emit_insn (gen_floatunssidf2 (r1, r0));
842 emit_insn (gen_subdf3 (operands[0], r1, c1));
846 (define_expand "floatunssidf2"
847 [(set (match_operand:DF 0 "register_operand" "=r")
848 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
852 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
853 0x06071415, 0x16178080);
854 rtx r0 = gen_reg_rtx (V16QImode);
860 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
862 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
863 insns = get_insns ();
865 emit_libcall_block (insns, operands[0], value,
866 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
870 emit_move_insn (r0, c0);
871 emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
876 (define_insn_and_split "floatunssidf2_internal"
877 [(set (match_operand:DF 0 "register_operand" "=r")
878 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))
879 (use (match_operand:V16QI 2 "register_operand" "r"))
880 (clobber (match_scratch:V4SI 3 "=&r"))
881 (clobber (match_scratch:V4SI 4 "=&r"))
882 (clobber (match_scratch:V4SI 5 "=&r"))
883 (clobber (match_scratch:V4SI 6 "=&r"))]
885 "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"
887 [(set (match_dup:DF 0)
888 (unsigned_float:DF (match_dup:SI 1)))]
891 rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
892 rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
893 rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
894 rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
895 emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
896 emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
897 emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
898 emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
899 emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
900 emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
901 emit_insn (gen_andc_v4si (ops[6],ops[6],ops[5]));
902 emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
903 emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
906 [(set_attr "length" "32")])
908 (define_expand "floatdidf2"
909 [(set (match_operand:DF 0 "register_operand" "")
910 (float:DF (match_operand:DI 1 "register_operand" "")))]
913 rtx c0 = gen_reg_rtx (DImode);
914 rtx r0 = gen_reg_rtx (DImode);
915 rtx r1 = gen_reg_rtx (DFmode);
916 rtx r2 = gen_reg_rtx (DImode);
917 rtx setneg = gen_reg_rtx (DImode);
918 rtx isneg = gen_reg_rtx (SImode);
919 rtx neg = gen_reg_rtx (DImode);
920 rtx mask = gen_reg_rtx (DImode);
922 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
924 emit_insn (gen_negdi2 (neg, operands[1]));
925 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
926 emit_insn (gen_extend_compare (mask, isneg));
927 emit_insn (gen_selb (r0, neg, operands[1], mask));
928 emit_insn (gen_andc_di (setneg, c0, mask));
930 emit_insn (gen_floatunsdidf2 (r1, r0));
932 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
933 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
937 (define_expand "floatunsdidf2"
938 [(set (match_operand:DF 0 "register_operand" "=r")
939 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
943 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
944 0x06071415, 0x16178080);
945 rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
946 rtx r0 = gen_reg_rtx (V16QImode);
947 rtx r1 = gen_reg_rtx (V4SImode);
953 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
955 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
956 insns = get_insns ();
958 emit_libcall_block (insns, operands[0], value,
959 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
963 emit_move_insn (r1, c1);
964 emit_move_insn (r0, c0);
965 emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
970 (define_insn_and_split "floatunsdidf2_internal"
971 [(set (match_operand:DF 0 "register_operand" "=r")
972 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))
973 (use (match_operand:V16QI 2 "register_operand" "r"))
974 (use (match_operand:V4SI 3 "register_operand" "r"))
975 (clobber (match_scratch:V4SI 4 "=&r"))
976 (clobber (match_scratch:V4SI 5 "=&r"))
977 (clobber (match_scratch:V4SI 6 "=&r"))]
979 "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"
981 [(set (match_operand:DF 0 "register_operand" "=r")
982 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
985 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
986 rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
987 rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
988 rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
989 rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
990 rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
991 emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
992 emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
993 emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
994 emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
995 emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
996 emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
997 emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
998 emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
999 emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
1000 emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
1003 [(set_attr "length" "40")])
1008 (define_expand "addv16qi3"
1009 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1010 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1011 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1014 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1015 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1016 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1017 rtx rhs_and = gen_reg_rtx (V8HImode);
1018 rtx hi_char = gen_reg_rtx (V8HImode);
1019 rtx lo_char = gen_reg_rtx (V8HImode);
1020 rtx mask = gen_reg_rtx (V8HImode);
1022 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1023 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1024 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
1025 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
1026 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1030 (define_insn "add<mode>3"
1031 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1032 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1033 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
1039 (define_expand "add<mode>3"
1040 [(set (match_dup:VDI 3)
1041 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1042 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
1043 (set (match_dup:VDI 5)
1044 (unspec:VDI [(match_dup 3)
1046 (match_dup:TI 4)] UNSPEC_SHUFB))
1047 (set (match_operand:VDI 0 "spu_reg_operand" "")
1048 (unspec:VDI [(match_dup 1)
1050 (match_dup 5)] UNSPEC_ADDX))]
1053 unsigned char pat[16] = {
1054 0x04, 0x05, 0x06, 0x07,
1055 0x80, 0x80, 0x80, 0x80,
1056 0x0c, 0x0d, 0x0e, 0x0f,
1057 0x80, 0x80, 0x80, 0x80
1059 operands[3] = gen_reg_rtx (<MODE>mode);
1060 operands[4] = gen_reg_rtx (TImode);
1061 operands[5] = gen_reg_rtx (<MODE>mode);
1062 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1065 (define_insn "cg_<mode>"
1066 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1067 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1068 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
1072 (define_insn "cgx_<mode>"
1073 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1074 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1075 (match_operand 2 "spu_reg_operand" "r")
1076 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1080 (define_insn "addx_<mode>"
1081 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1082 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1083 (match_operand 2 "spu_reg_operand" "r")
1084 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1089 ;; This is not the most efficient implementation of addti3.
1090 ;; We include this here because 1) the compiler needs it to be
1091 ;; defined as the word size is 128-bit and 2) sometimes gcc
1092 ;; substitutes an add for a constant left-shift. 2) is unlikely
1093 ;; because we also give addti3 a high cost. In case gcc does
1094 ;; generate TImode add, here is the code to do it.
1095 ;; operand 2 is a nonmemory because the compiler requires it.
1096 (define_insn "addti3"
1097 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1098 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1099 (match_operand:TI 2 "spu_nonmem_operand" "r")))
1100 (clobber (match_scratch:TI 3 "=&r"))]
1103 shlqbyi\t%3,%3,4\n\\
1105 shlqbyi\t%3,%3,4\n\\
1107 shlqbyi\t%0,%3,4\n\\
1109 [(set_attr "type" "multi0")
1110 (set_attr "length" "28")])
1112 (define_insn "add<mode>3"
1113 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1114 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1115 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1118 [(set_attr "type" "fp6")])
1120 (define_insn "add<mode>3"
1121 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1122 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1123 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1126 [(set_attr "type" "fpd")])
1131 (define_expand "subv16qi3"
1132 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1133 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1134 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1137 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1138 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1139 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1140 rtx rhs_and = gen_reg_rtx (V8HImode);
1141 rtx hi_char = gen_reg_rtx (V8HImode);
1142 rtx lo_char = gen_reg_rtx (V8HImode);
1143 rtx mask = gen_reg_rtx (V8HImode);
1145 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1146 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1147 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1148 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1149 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1153 (define_insn "sub<mode>3"
1154 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1155 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1156 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1162 (define_expand "sub<mode>3"
1163 [(set (match_dup:VDI 3)
1164 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1165 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1166 (set (match_dup:VDI 5)
1167 (unspec:VDI [(match_dup 3)
1169 (match_dup:TI 4)] UNSPEC_SHUFB))
1170 (set (match_operand:VDI 0 "spu_reg_operand" "")
1171 (unspec:VDI [(match_dup 1)
1173 (match_dup 5)] UNSPEC_SFX))]
1176 unsigned char pat[16] = {
1177 0x04, 0x05, 0x06, 0x07,
1178 0xc0, 0xc0, 0xc0, 0xc0,
1179 0x0c, 0x0d, 0x0e, 0x0f,
1180 0xc0, 0xc0, 0xc0, 0xc0
1182 operands[3] = gen_reg_rtx (<MODE>mode);
1183 operands[4] = gen_reg_rtx (TImode);
1184 operands[5] = gen_reg_rtx (<MODE>mode);
1185 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1188 (define_insn "bg_<mode>"
1189 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1190 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1191 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1195 (define_insn "bgx_<mode>"
1196 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1197 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1198 (match_operand 2 "spu_reg_operand" "r")
1199 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1203 (define_insn "sfx_<mode>"
1204 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1205 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1206 (match_operand 2 "spu_reg_operand" "r")
1207 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1211 (define_insn "subti3"
1212 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1213 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1214 (match_operand:TI 2 "spu_reg_operand" "r")))
1215 (clobber (match_scratch:TI 3 "=&r"))
1216 (clobber (match_scratch:TI 4 "=&r"))
1217 (clobber (match_scratch:TI 5 "=&r"))
1218 (clobber (match_scratch:TI 6 "=&r"))]
1224 shlqbyi\t%5,%3,4\n\\
1228 shlqbyi\t%5,%3,4\n\\
1232 shlqbyi\t%5,%3,4\n\\
1234 [(set_attr "type" "multi0")
1235 (set_attr "length" "56")])
1237 (define_insn "sub<mode>3"
1238 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1239 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1240 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1243 [(set_attr "type" "fp6")])
1245 (define_insn "sub<mode>3"
1246 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1247 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1248 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1251 [(set_attr "type" "fpd")])
1256 (define_expand "negv16qi2"
1257 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1258 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1261 rtx zero = gen_reg_rtx (V16QImode);
1262 emit_move_insn (zero, CONST0_RTX (V16QImode));
1263 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1267 (define_insn "neg<mode>2"
1268 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1269 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1273 (define_expand "negdi2"
1274 [(set (match_operand:DI 0 "spu_reg_operand" "")
1275 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1278 rtx zero = gen_reg_rtx(DImode);
1279 emit_move_insn(zero, GEN_INT(0));
1280 emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1284 (define_expand "negti2"
1285 [(set (match_operand:TI 0 "spu_reg_operand" "")
1286 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1289 rtx zero = gen_reg_rtx(TImode);
1290 emit_move_insn(zero, GEN_INT(0));
1291 emit_insn (gen_subti3(operands[0], zero, operands[1]));
1295 (define_expand "neg<mode>2"
1297 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1298 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1299 (use (match_dup 2))])]
1301 "operands[2] = gen_reg_rtx (<F2I>mode);
1302 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1304 (define_expand "neg<mode>2"
1306 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1307 (neg:VDF (match_operand:VDF 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, -0x8000000000000000ull));")
1313 (define_insn_and_split "_neg<mode>2"
1314 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1315 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1316 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1320 [(set (match_dup:<F2I> 3)
1321 (xor:<F2I> (match_dup:<F2I> 4)
1322 (match_dup:<F2I> 2)))]
1324 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1325 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1331 (define_expand "abs<mode>2"
1333 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1334 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1335 (use (match_dup 2))])]
1337 "operands[2] = gen_reg_rtx (<F2I>mode);
1338 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1340 (define_expand "abs<mode>2"
1342 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1343 (abs:VDF (match_operand:VDF 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, 0x7fffffffffffffffull));")
1349 (define_insn_and_split "_abs<mode>2"
1350 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1351 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1352 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1356 [(set (match_dup:<F2I> 3)
1357 (and:<F2I> (match_dup:<F2I> 4)
1358 (match_dup:<F2I> 2)))]
1360 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1361 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1367 (define_insn "mulhi3"
1368 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1369 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1370 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1375 [(set_attr "type" "fp7")])
1377 (define_expand "mulv8hi3"
1378 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1379 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1380 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1383 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1384 rtx low = gen_reg_rtx (V4SImode);
1385 rtx high = gen_reg_rtx (V4SImode);
1386 rtx shift = gen_reg_rtx (V4SImode);
1387 rtx mask = gen_reg_rtx (V4SImode);
1389 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1390 emit_insn (gen_vec_widen_smult_even_v8hi (high, operands[1], operands[2]));
1391 emit_insn (gen_vec_widen_smult_odd_v8hi (low, operands[1], operands[2]));
1392 emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1393 emit_insn (gen_selb (result, shift, low, mask));
1397 (define_expand "mul<mode>3"
1399 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1400 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1401 (match_operand:VSI 2 "spu_reg_operand" "")))
1402 (clobber (match_dup:VSI 3))
1403 (clobber (match_dup:VSI 4))
1404 (clobber (match_dup:VSI 5))
1405 (clobber (match_dup:VSI 6))])]
1408 operands[3] = gen_reg_rtx(<MODE>mode);
1409 operands[4] = gen_reg_rtx(<MODE>mode);
1410 operands[5] = gen_reg_rtx(<MODE>mode);
1411 operands[6] = gen_reg_rtx(<MODE>mode);
1414 (define_insn_and_split "_mulsi3"
1415 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1416 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1417 (match_operand:SI 2 "spu_arith_operand" "rK")))
1418 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1419 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1420 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1421 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1425 [(set (match_dup:SI 0)
1426 (mult:SI (match_dup:SI 1)
1429 HOST_WIDE_INT val = 0;
1430 rtx a = operands[3];
1431 rtx b = operands[4];
1432 rtx c = operands[5];
1433 rtx d = operands[6];
1434 if (GET_CODE(operands[2]) == CONST_INT)
1436 val = INTVAL(operands[2]);
1437 emit_move_insn(d, operands[2]);
1440 if (val && (val & 0xffff) == 0)
1442 emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1444 else if (val > 0 && val < 0x10000)
1446 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1447 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1448 emit_insn (gen_mpyu_si(c, operands[1], cst));
1449 emit_insn (gen_addsi3(operands[0], a, c));
1453 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1454 emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1455 emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1456 emit_insn (gen_addsi3(d, a, b));
1457 emit_insn (gen_addsi3(operands[0], d, c));
1462 (define_insn_and_split "_mulv4si3"
1463 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1464 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1465 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1466 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1467 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1468 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1469 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1473 [(set (match_dup:V4SI 0)
1474 (mult:V4SI (match_dup:V4SI 1)
1475 (match_dup:V4SI 2)))]
1477 rtx a = operands[3];
1478 rtx b = operands[4];
1479 rtx c = operands[5];
1480 rtx d = operands[6];
1481 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1482 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1483 emit_insn (gen_spu_mpyh(a, op1, op2));
1484 emit_insn (gen_spu_mpyh(b, op2, op1));
1485 emit_insn (gen_vec_widen_umult_odd_v8hi (c, op1, op2));
1486 emit_insn (gen_addv4si3(d, a, b));
1487 emit_insn (gen_addv4si3(operands[0], d, c));
1491 (define_insn "mulhisi3"
1492 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1493 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1494 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1497 [(set_attr "type" "fp7")])
1499 (define_insn "mulhisi3_imm"
1500 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1501 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1502 (match_operand:SI 2 "imm_K_operand" "K")))]
1505 [(set_attr "type" "fp7")])
1507 (define_insn "umulhisi3"
1508 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1509 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1510 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1513 [(set_attr "type" "fp7")])
1515 (define_insn "umulhisi3_imm"
1516 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1517 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1518 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1521 [(set_attr "type" "fp7")])
1523 (define_insn "mpyu_si"
1524 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1525 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1527 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1528 (const_int 65535))))]
1533 [(set_attr "type" "fp7")])
1535 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1536 ;; It's faster to do the multiplies in parallel then add them. If we
1537 ;; merge a multiply and add it prevents the multiplies from happening in
1539 (define_insn "mpya_si"
1540 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1541 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1542 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1543 (match_operand:SI 3 "spu_reg_operand" "r")))]
1546 [(set_attr "type" "fp7")])
1548 (define_insn "mpyh_si"
1549 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1550 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1552 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1553 (const_int 65535))))]
1556 [(set_attr "type" "fp7")])
1558 (define_insn "mpys_si"
1559 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1561 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1562 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1566 [(set_attr "type" "fp7")])
1568 (define_insn "mpyhh_si"
1569 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1570 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1572 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1576 [(set_attr "type" "fp7")])
1578 (define_insn "mpyhhu_si"
1579 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1580 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1582 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1586 [(set_attr "type" "fp7")])
1588 (define_insn "mpyhha_si"
1589 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1590 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1592 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1594 (match_operand:SI 3 "spu_reg_operand" "0")))]
1597 [(set_attr "type" "fp7")])
1599 (define_insn "mul<mode>3"
1600 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1601 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1602 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1605 [(set_attr "type" "fp<d6>")])
1607 (define_insn "fma<mode>4"
1608 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1609 (fma:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1610 (match_operand:VSF 2 "spu_reg_operand" "r")
1611 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1614 [(set_attr "type" "fp6")])
1616 ;; ??? The official description is (c - a*b), which is exactly (-a*b + c).
1617 ;; Note that this doesn't match the dfnms description. Incorrect?
1618 (define_insn "fnma<mode>4"
1619 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1621 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
1622 (match_operand:VSF 2 "spu_reg_operand" "r")
1623 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1626 [(set_attr "type" "fp6")])
1628 (define_insn "fms<mode>4"
1629 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1631 (match_operand:VSF 1 "spu_reg_operand" "r")
1632 (match_operand:VSF 2 "spu_reg_operand" "r")
1633 (neg:VSF (match_operand:VSF 3 "spu_reg_operand" "r"))))]
1636 [(set_attr "type" "fp6")])
1638 (define_insn "fma<mode>4"
1639 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1640 (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1641 (match_operand:VDF 2 "spu_reg_operand" "r")
1642 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1645 [(set_attr "type" "fpd")])
1647 (define_insn "fms<mode>4"
1648 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1650 (match_operand:VDF 1 "spu_reg_operand" "r")
1651 (match_operand:VDF 2 "spu_reg_operand" "r")
1652 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1655 [(set_attr "type" "fpd")])
1657 (define_insn "nfma<mode>4"
1658 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1660 (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1661 (match_operand:VDF 2 "spu_reg_operand" "r")
1662 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1665 [(set_attr "type" "fpd")])
1667 (define_insn "nfms<mode>4"
1668 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1671 (match_operand:VDF 1 "spu_reg_operand" "r")
1672 (match_operand:VDF 2 "spu_reg_operand" "r")
1673 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0")))))]
1676 [(set_attr "type" "fpd")])
1678 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
1679 (define_expand "fnma<mode>4"
1680 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1683 (match_operand:VDF 1 "spu_reg_operand" "")
1684 (match_operand:VDF 2 "spu_reg_operand" "")
1685 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "")))))]
1686 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1689 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
1690 (define_expand "fnms<mode>4"
1691 [(set (match_operand:VDF 0 "register_operand" "")
1694 (match_operand:VDF 1 "register_operand" "")
1695 (match_operand:VDF 2 "register_operand" "")
1696 (match_operand:VDF 3 "register_operand" ""))))]
1697 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1700 ;; mul highpart, used for divide by constant optimizations.
1702 (define_expand "smulsi3_highpart"
1703 [(set (match_operand:SI 0 "register_operand" "")
1706 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1707 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1711 rtx t0 = gen_reg_rtx (SImode);
1712 rtx t1 = gen_reg_rtx (SImode);
1713 rtx t2 = gen_reg_rtx (SImode);
1714 rtx t3 = gen_reg_rtx (SImode);
1715 rtx t4 = gen_reg_rtx (SImode);
1716 rtx t5 = gen_reg_rtx (SImode);
1717 rtx t6 = gen_reg_rtx (SImode);
1718 rtx t7 = gen_reg_rtx (SImode);
1719 rtx t8 = gen_reg_rtx (SImode);
1720 rtx t9 = gen_reg_rtx (SImode);
1721 rtx t11 = gen_reg_rtx (SImode);
1722 rtx t12 = gen_reg_rtx (SImode);
1723 rtx t14 = gen_reg_rtx (SImode);
1724 rtx t15 = gen_reg_rtx (HImode);
1725 rtx t16 = gen_reg_rtx (HImode);
1726 rtx t17 = gen_reg_rtx (HImode);
1727 rtx t18 = gen_reg_rtx (HImode);
1728 rtx t19 = gen_reg_rtx (SImode);
1729 rtx t20 = gen_reg_rtx (SImode);
1730 rtx t21 = gen_reg_rtx (SImode);
1731 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1732 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1733 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1734 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1736 rtx_insn *insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1737 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1738 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1739 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1740 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1741 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1742 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1743 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1745 /* Gen carry bits (in t9 and t11). */
1746 emit_insn (gen_addsi3 (t8, t2, t3));
1747 emit_insn (gen_cg_si (t9, t2, t3));
1748 emit_insn (gen_cg_si (t11, t8, t4));
1750 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1751 emit_insn (gen_addx_si (t12, t5, t6, t9));
1752 emit_insn (gen_addx_si (t14, t12, t7, t11));
1754 /* mpys treats both operands as signed when we really want it to treat
1755 the first operand as signed and the second operand as unsigned.
1756 The code below corrects for that difference. */
1757 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1758 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1759 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1760 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1761 emit_insn (gen_extendhisi2 (t19, t17));
1762 emit_insn (gen_extendhisi2 (t20, t18));
1763 emit_insn (gen_addsi3 (t21, t19, t20));
1764 emit_insn (gen_addsi3 (operands[0], t14, t21));
1765 unshare_all_rtl_in_chain (insn);
1769 (define_expand "umulsi3_highpart"
1770 [(set (match_operand:SI 0 "register_operand" "")
1773 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1774 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1779 rtx t0 = gen_reg_rtx (SImode);
1780 rtx t1 = gen_reg_rtx (SImode);
1781 rtx t2 = gen_reg_rtx (SImode);
1782 rtx t3 = gen_reg_rtx (SImode);
1783 rtx t4 = gen_reg_rtx (SImode);
1784 rtx t5 = gen_reg_rtx (SImode);
1785 rtx t6 = gen_reg_rtx (SImode);
1786 rtx t7 = gen_reg_rtx (SImode);
1787 rtx t8 = gen_reg_rtx (SImode);
1788 rtx t9 = gen_reg_rtx (SImode);
1789 rtx t10 = gen_reg_rtx (SImode);
1790 rtx t12 = gen_reg_rtx (SImode);
1791 rtx t13 = gen_reg_rtx (SImode);
1792 rtx t14 = gen_reg_rtx (SImode);
1793 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1794 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1795 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1797 rtx_insn *insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1798 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1799 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1800 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1801 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1802 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1803 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1804 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1805 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1807 /* Gen carry bits (in t10 and t12). */
1808 emit_insn (gen_addsi3 (t9, t1, t5));
1809 emit_insn (gen_cg_si (t10, t1, t5));
1810 emit_insn (gen_cg_si (t12, t9, t6));
1812 /* Gen high 32 bits in operand[0]. */
1813 emit_insn (gen_addx_si (t13, t4, t7, t10));
1814 emit_insn (gen_addx_si (t14, t13, t8, t12));
1815 emit_insn (gen_movsi (operands[0], t14));
1816 unshare_all_rtl_in_chain (insn);
1823 ;; Not necessarily the best implementation of divide but faster then
1824 ;; the default that gcc provides because this is inlined and it uses
1826 (define_insn "divmodsi4"
1827 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1828 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1829 (match_operand:SI 2 "spu_reg_operand" "r")))
1830 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1831 (mod:SI (match_dup 1)
1833 (clobber (match_scratch:SI 4 "=&r"))
1834 (clobber (match_scratch:SI 5 "=&r"))
1835 (clobber (match_scratch:SI 6 "=&r"))
1836 (clobber (match_scratch:SI 7 "=&r"))
1837 (clobber (match_scratch:SI 8 "=&r"))
1838 (clobber (match_scratch:SI 9 "=&r"))
1839 (clobber (match_scratch:SI 10 "=&r"))
1840 (clobber (match_scratch:SI 11 "=&r"))
1841 (clobber (match_scratch:SI 12 "=&r"))
1842 (clobber (reg:SI 130))]
1850 selb %8,%8,%1,%10\\n\\
1851 selb %9,%9,%2,%11\\n\\
1857 shlqbyi %3,%8,0\\n\\
1858 xor %11,%10,%11\\n\\
1862 1: or %12,%0,%5\\n\\
1863 rotqmbii %5,%5,-1\\n\\
1867 rotqmbii %4,%4,-1\\n\\
1868 selb %0,%12,%0,%6\\n\\
1870 selb %3,%7,%3,%6\\n\\
1874 selb %3,%8,%3,%10\\n\\
1876 [(set_attr "type" "multi0")
1877 (set_attr "length" "128")])
1879 (define_insn "udivmodsi4"
1880 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1881 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1882 (match_operand:SI 2 "spu_reg_operand" "r")))
1883 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1884 (umod:SI (match_dup 1)
1886 (clobber (match_scratch:SI 4 "=&r"))
1887 (clobber (match_scratch:SI 5 "=&r"))
1888 (clobber (match_scratch:SI 6 "=&r"))
1889 (clobber (match_scratch:SI 7 "=&r"))
1890 (clobber (match_scratch:SI 8 "=&r"))
1891 (clobber (reg:SI 130))]
1904 rotqmbii %5,%5,-1\\n\\
1908 rotqmbii %4,%4,-1\\n\\
1909 selb %0,%8,%0,%6\\n\\
1911 selb %3,%7,%3,%6\\n\\
1914 [(set_attr "type" "multi0")
1915 (set_attr "length" "80")])
1917 (define_expand "div<mode>3"
1919 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1920 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1921 (match_operand:VSF 2 "spu_reg_operand" "")))
1922 (clobber (match_scratch:VSF 3 ""))
1923 (clobber (match_scratch:VSF 4 ""))
1924 (clobber (match_scratch:VSF 5 ""))])]
1928 (define_insn_and_split "*div<mode>3_fast"
1929 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1930 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1931 (match_operand:VSF 2 "spu_reg_operand" "r")))
1932 (clobber (match_scratch:VSF 3 "=&r"))
1933 (clobber (match_scratch:VSF 4 "=&r"))
1934 (clobber (scratch:VSF))]
1935 "flag_unsafe_math_optimizations"
1938 [(set (match_dup:VSF 0)
1939 (div:VSF (match_dup:VSF 1)
1941 (clobber (match_dup:VSF 3))
1942 (clobber (match_dup:VSF 4))
1943 (clobber (scratch:VSF))]
1945 emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1946 emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1947 emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1948 emit_insn (gen_fnma<mode>4(operands[0], operands[4], operands[2], operands[1]));
1949 emit_insn (gen_fma<mode>4(operands[0], operands[0], operands[3], operands[4]));
1953 (define_insn_and_split "*div<mode>3_adjusted"
1954 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1955 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1956 (match_operand:VSF 2 "spu_reg_operand" "r")))
1957 (clobber (match_scratch:VSF 3 "=&r"))
1958 (clobber (match_scratch:VSF 4 "=&r"))
1959 (clobber (match_scratch:VSF 5 "=&r"))]
1960 "!flag_unsafe_math_optimizations"
1963 [(set (match_dup:VSF 0)
1964 (div:VSF (match_dup:VSF 1)
1966 (clobber (match_dup:VSF 3))
1967 (clobber (match_dup:VSF 4))
1968 (clobber (match_dup:VSF 5))]
1970 emit_insn (gen_frest_<mode> (operands[3], operands[2]));
1971 emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
1972 emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
1973 emit_insn (gen_fnma<mode>4 (operands[5], operands[4], operands[2], operands[1]));
1974 emit_insn (gen_fma<mode>4 (operands[3], operands[5], operands[3], operands[4]));
1976 /* Due to truncation error, the quotient result may be low by 1 ulp.
1977 Conditionally add one if the estimate is too small in magnitude. */
1979 emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
1980 spu_const (<F2I>mode, 0x80000000ULL));
1981 emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
1982 spu_const (<F2I>mode, 0x3f800000ULL));
1983 emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1985 emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
1986 gen_lowpart (<F2I>mode, operands[3]),
1987 spu_const (<F2I>mode, 1)));
1988 emit_insn (gen_fnma<mode>4 (operands[0], operands[2], operands[4], operands[1]));
1989 emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
1990 emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
1991 gen_lowpart (<F2I>mode, operands[0]),
1992 spu_const (<F2I>mode, -1)));
1993 emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
2000 (define_insn_and_split "sqrtsf2"
2001 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
2002 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
2003 (clobber (match_scratch:SF 2 "=&r"))
2004 (clobber (match_scratch:SF 3 "=&r"))
2005 (clobber (match_scratch:SF 4 "=&r"))
2006 (clobber (match_scratch:SF 5 "=&r"))]
2010 [(set (match_dup:SF 0)
2011 (sqrt:SF (match_dup:SF 1)))
2012 (clobber (match_dup:SF 2))
2013 (clobber (match_dup:SF 3))
2014 (clobber (match_dup:SF 4))
2015 (clobber (match_dup:SF 5))]
2017 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
2018 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
2019 emit_insn (gen_frsqest_sf(operands[2],operands[1]));
2020 emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
2021 emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
2022 emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
2023 emit_insn (gen_fnmasf4(operands[4],operands[2],operands[5],operands[4]));
2024 emit_insn (gen_fmasf4(operands[0],operands[4],operands[3],operands[5]));
2028 (define_insn "frest_<mode>"
2029 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2030 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
2033 [(set_attr "type" "shuf")])
2035 (define_insn "frsqest_<mode>"
2036 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2037 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
2040 [(set_attr "type" "shuf")])
2042 (define_insn "fi_<mode>"
2043 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2044 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
2045 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
2048 [(set_attr "type" "fp7")])
2053 (define_insn "and<mode>3"
2054 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2055 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2056 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
2060 and%j2i\t%0,%1,%J2")
2062 (define_insn "anddi3"
2063 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2064 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2065 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2069 and%k2i\t%0,%1,%K2")
2071 (define_insn "andti3"
2072 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2073 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2074 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2078 and%m2i\t%0,%1,%L2")
2080 (define_insn "andc_<mode>"
2081 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2082 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2083 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2087 (define_insn "nand_<mode>"
2088 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2089 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
2090 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
2097 (define_insn "ior<mode>3"
2098 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
2099 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2100 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2107 (define_insn "iordi3"
2108 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2109 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2110 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2117 (define_insn "iorti3"
2118 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2119 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2120 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2127 (define_insn "orc_<mode>"
2128 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2129 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2130 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2134 (define_insn "nor_<mode>"
2135 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2136 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2137 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2143 (define_insn "xor<mode>3"
2144 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2145 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2146 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2150 xor%j2i\t%0,%1,%J2")
2152 (define_insn "xordi3"
2153 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2154 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2155 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2159 xor%k2i\t%0,%1,%K2")
2161 (define_insn "xorti3"
2162 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2163 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2164 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2168 xor%m2i\t%0,%1,%L2")
2170 (define_insn "eqv_<mode>"
2171 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2172 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2173 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2179 (define_insn "one_cmpl<mode>2"
2180 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2181 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2188 (define_expand "selb"
2189 [(set (match_operand 0 "spu_reg_operand" "")
2190 (unspec [(match_operand 1 "spu_reg_operand" "")
2191 (match_operand 2 "spu_reg_operand" "")
2192 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2195 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2196 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2201 ;; This could be defined as a combination of logical operations, but at
2202 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2203 (define_insn "_selb"
2204 [(set (match_operand 0 "spu_reg_operand" "=r")
2205 (unspec [(match_operand 1 "spu_reg_operand" "r")
2206 (match_operand 2 "spu_reg_operand" "r")
2207 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2208 "GET_MODE(operands[0]) == GET_MODE(operands[1])
2209 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2210 "selb\t%0,%1,%2,%3")
2213 ;; Misc. byte/bit operations
2214 ;; clz/ctz/ffs/popcount/parity
2217 (define_insn "clz<mode>2"
2218 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2219 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2223 (define_expand "ctz<mode>2"
2225 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2226 (set (match_dup 3) (and:VSI (match_dup 1)
2228 (set (match_dup 4) (clz:VSI (match_dup 3)))
2229 (set (match_operand:VSI 0 "spu_reg_operand" "")
2230 (minus:VSI (match_dup 5) (match_dup 4)))]
2233 operands[2] = gen_reg_rtx (<MODE>mode);
2234 operands[3] = gen_reg_rtx (<MODE>mode);
2235 operands[4] = gen_reg_rtx (<MODE>mode);
2236 operands[5] = spu_const(<MODE>mode, 31);
2239 (define_expand "clrsb<mode>2"
2241 (gt:VSI (match_operand:VSI 1 "spu_reg_operand" "") (match_dup 5)))
2242 (set (match_dup 3) (not:VSI (xor:VSI (match_dup 1) (match_dup 2))))
2243 (set (match_dup 4) (clz:VSI (match_dup 3)))
2244 (set (match_operand:VSI 0 "spu_reg_operand")
2245 (plus:VSI (match_dup 4) (match_dup 5)))]
2248 operands[2] = gen_reg_rtx (<MODE>mode);
2249 operands[3] = gen_reg_rtx (<MODE>mode);
2250 operands[4] = gen_reg_rtx (<MODE>mode);
2251 operands[5] = spu_const(<MODE>mode, -1);
2254 (define_expand "ffs<mode>2"
2256 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2257 (set (match_dup 3) (and:VSI (match_dup 1)
2259 (set (match_dup 4) (clz:VSI (match_dup 3)))
2260 (set (match_operand:VSI 0 "spu_reg_operand" "")
2261 (minus:VSI (match_dup 5) (match_dup 4)))]
2264 operands[2] = gen_reg_rtx (<MODE>mode);
2265 operands[3] = gen_reg_rtx (<MODE>mode);
2266 operands[4] = gen_reg_rtx (<MODE>mode);
2267 operands[5] = spu_const(<MODE>mode, 32);
2270 (define_expand "popcountsi2"
2272 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2275 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2276 (set (match_operand:SI 0 "spu_reg_operand" "")
2277 (sign_extend:SI (match_dup 3)))]
2280 operands[2] = gen_reg_rtx (SImode);
2281 operands[3] = gen_reg_rtx (HImode);
2284 (define_expand "paritysi2"
2285 [(set (match_operand:SI 0 "spu_reg_operand" "")
2286 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2289 operands[2] = gen_reg_rtx (SImode);
2290 emit_insn (gen_popcountsi2(operands[2], operands[1]));
2291 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2295 (define_insn "cntb_si"
2296 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2297 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2301 [(set_attr "type" "fxb")])
2303 (define_insn "cntb_v16qi"
2304 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2305 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2309 [(set_attr "type" "fxb")])
2311 (define_insn "sumb_si"
2312 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2313 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2316 [(set_attr "type" "fxb")])
2321 (define_insn "<v>ashl<mode>3"
2322 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2323 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2324 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2328 shl<bh>i\t%0,%1,%<umask>2"
2329 [(set_attr "type" "fx3")])
2331 (define_insn_and_split "ashldi3"
2332 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2333 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2334 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2335 (clobber (match_scratch:SI 3 "=&r,X"))]
2339 [(set (match_dup:DI 0)
2340 (ashift:DI (match_dup:DI 1)
2343 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2344 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2345 rtx op2 = operands[2];
2346 rtx op3 = operands[3];
2348 if (GET_CODE (operands[2]) == REG)
2350 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2351 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2352 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2353 emit_insn (gen_shlqbi_ti (op0, op0, op3));
2357 HOST_WIDE_INT val = INTVAL (operands[2]);
2358 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2359 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2361 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2366 (define_expand "ashlti3"
2367 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2368 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2369 (match_operand:SI 2 "spu_nonmem_operand" "")))
2370 (clobber (match_dup:TI 3))])]
2372 "if (GET_CODE (operands[2]) == CONST_INT)
2374 emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2377 operands[3] = gen_reg_rtx (TImode);")
2379 (define_insn_and_split "ashlti3_imm"
2380 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2381 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2382 (match_operand:SI 2 "immediate_operand" "O,P")))]
2387 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2388 [(set (match_dup:TI 0)
2389 (ashift:TI (match_dup:TI 1)
2391 (set (match_dup:TI 0)
2392 (ashift:TI (match_dup:TI 0)
2395 HOST_WIDE_INT val = INTVAL(operands[2]);
2396 operands[3] = GEN_INT (val&7);
2397 operands[4] = GEN_INT (val&-8);
2399 [(set_attr "type" "shuf,shuf")])
2401 (define_insn_and_split "ashlti3_reg"
2402 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2403 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2404 (match_operand:SI 2 "spu_reg_operand" "r")))
2405 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2409 [(set (match_dup:TI 3)
2410 (ashift:TI (match_dup:TI 1)
2411 (and:SI (match_dup:SI 2)
2413 (set (match_dup:TI 0)
2414 (ashift:TI (match_dup:TI 3)
2415 (and:SI (match_dup:SI 2)
2419 (define_insn "shlqbybi_ti"
2420 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2421 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2422 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2428 [(set_attr "type" "shuf,shuf")])
2430 (define_insn "shlqbi_ti"
2431 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2432 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2433 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2439 [(set_attr "type" "shuf,shuf")])
2441 (define_insn "shlqby_ti"
2442 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2443 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2444 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2450 [(set_attr "type" "shuf,shuf")])
2455 (define_insn_and_split "<v>lshr<mode>3"
2456 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2457 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2458 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2459 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2463 rot<bh>mi\t%0,%1,-%<umask>2"
2464 "reload_completed && GET_CODE (operands[2]) == REG"
2465 [(set (match_dup:VHSI 3)
2466 (neg:VHSI (match_dup:VHSI 2)))
2467 (set (match_dup:VHSI 0)
2468 (lshiftrt:VHSI (match_dup:VHSI 1)
2469 (neg:VHSI (match_dup:VHSI 3))))]
2471 [(set_attr "type" "*,fx3")])
2473 (define_insn "<v>lshr<mode>3_imm"
2474 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2475 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2476 (match_operand:VHSI 2 "immediate_operand" "W")))]
2478 "rot<bh>mi\t%0,%1,-%<umask>2"
2479 [(set_attr "type" "fx3")])
2481 (define_insn "rotm_<mode>"
2482 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2483 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2484 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2488 rot<bh>mi\t%0,%1,-%<nmask>2"
2489 [(set_attr "type" "fx3")])
2491 (define_insn_and_split "lshr<mode>3"
2492 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2493 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2494 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2498 rotqmbyi\t%0,%1,-%h2
2499 rotqmbii\t%0,%1,-%e2"
2500 "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2501 [(set (match_dup:DTI 3)
2502 (lshiftrt:DTI (match_dup:DTI 1)
2504 (set (match_dup:DTI 0)
2505 (lshiftrt:DTI (match_dup:DTI 3)
2508 operands[3] = gen_reg_rtx (<MODE>mode);
2509 if (GET_CODE (operands[2]) == CONST_INT)
2511 HOST_WIDE_INT val = INTVAL(operands[2]);
2512 operands[4] = GEN_INT (val & 7);
2513 operands[5] = GEN_INT (val & -8);
2517 rtx t0 = gen_reg_rtx (SImode);
2518 rtx t1 = gen_reg_rtx (SImode);
2519 emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2520 emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2521 operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2522 operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2525 [(set_attr "type" "*,shuf,shuf")])
2527 (define_expand "shrqbybi_<mode>"
2528 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2529 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2530 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2535 if (GET_CODE (operands[2]) == CONST_INT)
2536 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2539 rtx t0 = gen_reg_rtx (SImode);
2540 emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2545 (define_insn "rotqmbybi_<mode>"
2546 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2547 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2548 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2554 rotqmbyi\t%0,%1,-%H2"
2555 [(set_attr "type" "shuf")])
2557 (define_insn_and_split "shrqbi_<mode>"
2558 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2559 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2560 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2562 (clobber (match_scratch:SI 3 "=&r,X"))]
2566 [(set (match_dup:DTI 0)
2567 (lshiftrt:DTI (match_dup:DTI 1)
2568 (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2570 if (GET_CODE (operands[2]) == CONST_INT)
2571 operands[3] = GEN_INT (-INTVAL (operands[2]));
2573 emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2575 [(set_attr "type" "shuf")])
2577 (define_insn "rotqmbi_<mode>"
2578 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2579 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2580 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2585 rotqmbii\t%0,%1,-%E2"
2586 [(set_attr "type" "shuf")])
2588 (define_expand "shrqby_<mode>"
2589 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2590 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2591 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2595 if (GET_CODE (operands[2]) == CONST_INT)
2596 operands[2] = GEN_INT (-INTVAL (operands[2]));
2599 rtx t0 = gen_reg_rtx (SImode);
2600 emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2605 (define_insn "rotqmby_<mode>"
2606 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2607 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2608 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2613 rotqmbyi\t%0,%1,-%F2"
2614 [(set_attr "type" "shuf")])
2619 (define_insn_and_split "<v>ashr<mode>3"
2620 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2621 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2622 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2623 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2627 rotma<bh>i\t%0,%1,-%<umask>2"
2628 "reload_completed && GET_CODE (operands[2]) == REG"
2629 [(set (match_dup:VHSI 3)
2630 (neg:VHSI (match_dup:VHSI 2)))
2631 (set (match_dup:VHSI 0)
2632 (ashiftrt:VHSI (match_dup:VHSI 1)
2633 (neg:VHSI (match_dup:VHSI 3))))]
2635 [(set_attr "type" "*,fx3")])
2637 (define_insn "<v>ashr<mode>3_imm"
2638 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2639 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2640 (match_operand:VHSI 2 "immediate_operand" "W")))]
2642 "rotma<bh>i\t%0,%1,-%<umask>2"
2643 [(set_attr "type" "fx3")])
2646 (define_insn "rotma_<mode>"
2647 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2648 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2649 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2653 rotma<bh>i\t%0,%1,-%<nmask>2"
2654 [(set_attr "type" "fx3")])
2656 (define_insn_and_split "ashrdi3"
2657 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2658 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2659 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2660 (clobber (match_scratch:TI 3 "=&r,&r"))
2661 (clobber (match_scratch:TI 4 "=&r,&r"))
2662 (clobber (match_scratch:SI 5 "=&r,&r"))]
2666 [(set (match_dup:DI 0)
2667 (ashiftrt:DI (match_dup:DI 1)
2670 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2671 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2672 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2673 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2674 rtx op2 = operands[2];
2675 rtx op3 = operands[3];
2676 rtx op4 = operands[4];
2677 rtx op5 = operands[5];
2679 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2681 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2682 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2683 emit_insn (gen_spu_fsm (op0v, op0s));
2685 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2687 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2688 HOST_WIDE_INT val = INTVAL (op2);
2689 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2690 emit_insn (gen_spu_xswd (op0d, op0v));
2692 emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2696 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2697 unsigned char arr[16] = {
2698 0xff, 0xff, 0xff, 0xff,
2699 0xff, 0xff, 0xff, 0xff,
2700 0x00, 0x00, 0x00, 0x00,
2701 0x00, 0x00, 0x00, 0x00
2704 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2705 emit_move_insn (op4, array_to_constant (TImode, arr));
2706 emit_insn (gen_spu_fsm (op3v, op5));
2708 if (GET_CODE (operands[2]) == REG)
2710 emit_insn (gen_selb (op4, op3, op1, op4));
2711 emit_insn (gen_negsi2 (op5, op2));
2712 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2713 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2717 HOST_WIDE_INT val = -INTVAL (op2);
2718 emit_insn (gen_selb (op0, op3, op1, op4));
2720 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2722 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2729 (define_insn_and_split "ashrti3"
2730 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2731 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2732 (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2736 [(set (match_dup:TI 0)
2737 (ashiftrt:TI (match_dup:TI 1)
2740 rtx sign_shift = gen_reg_rtx (SImode);
2741 rtx sign_mask = gen_reg_rtx (TImode);
2742 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2743 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2744 rtx t = gen_reg_rtx (TImode);
2745 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2746 emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2747 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2748 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2749 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2750 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2754 ;; fsm is used after rotam to replicate the sign across the whole register.
2755 (define_insn "fsm_ti"
2756 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2757 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2760 [(set_attr "type" "shuf")])
2765 (define_insn "<v>rotl<mode>3"
2766 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2767 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2768 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2772 rot<bh>i\t%0,%1,%<umask>2"
2773 [(set_attr "type" "fx3")])
2775 (define_insn "rotlti3"
2776 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2777 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2778 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2781 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2784 rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2785 [(set_attr "length" "8,4,4,8")
2786 (set_attr "type" "multi1,shuf,shuf,multi1")])
2788 (define_insn "rotqbybi_ti"
2789 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2790 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2791 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2797 [(set_attr "type" "shuf,shuf")])
2799 (define_insn "rotqby_ti"
2800 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2801 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2802 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2808 [(set_attr "type" "shuf,shuf")])
2810 (define_insn "rotqbi_ti"
2811 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2812 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2813 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2819 [(set_attr "type" "shuf,shuf")])
2822 ;; struct extract/insert
2823 ;; We handle mem's because GCC will generate invalid SUBREG's
2824 ;; and inefficient code.
2826 (define_expand "extv"
2827 [(set (match_operand:TI 0 "register_operand" "")
2828 (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2829 (match_operand:SI 2 "const_int_operand" "")
2830 (match_operand:SI 3 "const_int_operand" "")))]
2833 spu_expand_extv (operands, 0);
2837 (define_expand "extzv"
2838 [(set (match_operand:TI 0 "register_operand" "")
2839 (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2840 (match_operand:SI 2 "const_int_operand" "")
2841 (match_operand:SI 3 "const_int_operand" "")))]
2844 spu_expand_extv (operands, 1);
2848 (define_expand "insv"
2849 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2850 (match_operand:SI 1 "const_int_operand" "")
2851 (match_operand:SI 2 "const_int_operand" ""))
2852 (match_operand 3 "nonmemory_operand" ""))]
2855 if (INTVAL (operands[1]) + INTVAL (operands[2])
2856 > GET_MODE_BITSIZE (GET_MODE (operands[0])))
2858 spu_expand_insv(operands);
2862 ;; Simplify a number of patterns that get generated by extv, extzv,
2864 (define_insn_and_split "trunc_shr_ti<mode>"
2865 [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2866 (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2873 spu_split_convert (operands);
2876 [(set_attr "type" "convert")
2877 (set_attr "length" "0")])
2879 (define_insn_and_split "trunc_shr_tidi"
2880 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2881 (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2888 spu_split_convert (operands);
2891 [(set_attr "type" "convert")
2892 (set_attr "length" "0")])
2894 (define_insn_and_split "shl_ext_<mode>ti"
2895 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2896 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2903 spu_split_convert (operands);
2906 [(set_attr "type" "convert")
2907 (set_attr "length" "0")])
2909 (define_insn_and_split "shl_ext_diti"
2910 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2911 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2918 spu_split_convert (operands);
2921 [(set_attr "type" "convert")
2922 (set_attr "length" "0")])
2924 (define_insn "sext_trunc_lshr_tiqisi"
2925 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2926 (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2927 (const_int 120)]))))]
2930 [(set_attr "type" "fx3")])
2932 (define_insn "zext_trunc_lshr_tiqisi"
2933 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2934 (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2935 (const_int 120)]))))]
2938 [(set_attr "type" "fx3")])
2940 (define_insn "sext_trunc_lshr_tihisi"
2941 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2942 (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2943 (const_int 112)]))))]
2946 [(set_attr "type" "fx3")])
2948 (define_insn "zext_trunc_lshr_tihisi"
2949 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2950 (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2951 (const_int 112)]))))]
2954 [(set_attr "type" "fx3")])
2957 ;; String/block move insn.
2958 ;; Argument 0 is the destination
2959 ;; Argument 1 is the source
2960 ;; Argument 2 is the length
2961 ;; Argument 3 is the alignment
2963 (define_expand "movstrsi"
2964 [(parallel [(set (match_operand:BLK 0 "" "")
2965 (match_operand:BLK 1 "" ""))
2966 (use (match_operand:SI 2 "" ""))
2967 (use (match_operand:SI 3 "" ""))])]
2971 if (spu_expand_block_move (operands))
2980 (define_insn "indirect_jump"
2981 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2984 [(set_attr "type" "br")])
2988 (label_ref (match_operand 0 "" "")))]
2991 [(set_attr "type" "br")])
2996 ;; This will be used for leaf functions, that don't save any regs and
2997 ;; don't have locals on stack, maybe... that is for functions that
2998 ;; don't change $sp and don't need to save $lr.
2999 (define_expand "return"
3004 ;; used in spu_expand_epilogue to generate return from a function and
3005 ;; explicitly set use of $lr.
3007 (define_insn "_return"
3011 [(set_attr "type" "br")])
3017 (define_insn "ceq_<mode>"
3018 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3019 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3020 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3024 ceq<bh>i\t%0,%1,%2")
3026 (define_insn_and_split "ceq_di"
3027 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3028 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
3029 (match_operand:DI 2 "spu_reg_operand" "r")))]
3033 [(set (match_dup:SI 0)
3034 (eq:SI (match_dup:DI 1)
3037 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3038 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3039 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3040 emit_insn (gen_ceq_v4si (op0, op1, op2));
3041 emit_insn (gen_spu_gb (op0, op0));
3042 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
3047 ;; We provide the TI compares for completeness and because some parts of
3048 ;; gcc/libgcc use them, even though user code might never see it.
3049 (define_insn "ceq_ti"
3050 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3051 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
3052 (match_operand:TI 2 "spu_reg_operand" "r")))]
3054 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
3055 [(set_attr "type" "multi0")
3056 (set_attr "length" "12")])
3058 (define_insn "ceq_<mode>"
3059 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3060 (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3061 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3065 (define_insn "cmeq_<mode>"
3066 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3067 (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3068 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3072 ;; These implementations will ignore checking of NaN or INF if
3073 ;; compiled with option -ffinite-math-only.
3074 (define_expand "ceq_df"
3075 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3076 (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
3077 (match_operand:DF 2 "const_zero_operand" "i")))]
3080 if (spu_arch == PROCESSOR_CELL)
3082 rtx ra = gen_reg_rtx (V4SImode);
3083 rtx rb = gen_reg_rtx (V4SImode);
3084 rtx temp = gen_reg_rtx (TImode);
3085 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3086 rtx temp2 = gen_reg_rtx (V4SImode);
3087 rtx biteq = gen_reg_rtx (V4SImode);
3088 rtx ahi_inf = gen_reg_rtx (V4SImode);
3089 rtx a_nan = gen_reg_rtx (V4SImode);
3090 rtx a_abs = gen_reg_rtx (V4SImode);
3091 rtx b_abs = gen_reg_rtx (V4SImode);
3092 rtx iszero = gen_reg_rtx (V4SImode);
3093 rtx sign_mask = gen_reg_rtx (V4SImode);
3094 rtx nan_mask = gen_reg_rtx (V4SImode);
3095 rtx hihi_promote = gen_reg_rtx (TImode);
3096 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3097 0x7FFFFFFF, 0xFFFFFFFF);
3099 emit_move_insn (sign_mask, pat);
3100 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3102 emit_move_insn (nan_mask, pat);
3103 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3104 0x08090A0B, 0x18191A1B);
3105 emit_move_insn (hihi_promote, pat);
3107 emit_insn (gen_spu_convert (ra, operands[1]));
3108 emit_insn (gen_spu_convert (rb, operands[2]));
3109 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3110 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3112 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3114 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3115 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3116 if (!flag_finite_math_only)
3118 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3119 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3120 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3122 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3123 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3125 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3126 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3127 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3129 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3130 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3131 if (!flag_finite_math_only)
3133 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3135 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3140 (define_insn "ceq_<mode>_celledp"
3141 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3142 (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3143 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3144 "spu_arch == PROCESSOR_CELLEDP"
3146 [(set_attr "type" "fpd")])
3148 (define_insn "cmeq_<mode>_celledp"
3149 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3150 (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3151 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3152 "spu_arch == PROCESSOR_CELLEDP"
3154 [(set_attr "type" "fpd")])
3156 (define_expand "ceq_v2df"
3157 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3158 (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3159 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3162 if (spu_arch == PROCESSOR_CELL)
3164 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3165 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3166 rtx temp = gen_reg_rtx (TImode);
3167 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3168 rtx temp2 = gen_reg_rtx (V4SImode);
3169 rtx biteq = gen_reg_rtx (V4SImode);
3170 rtx ahi_inf = gen_reg_rtx (V4SImode);
3171 rtx a_nan = gen_reg_rtx (V4SImode);
3172 rtx a_abs = gen_reg_rtx (V4SImode);
3173 rtx b_abs = gen_reg_rtx (V4SImode);
3174 rtx iszero = gen_reg_rtx (V4SImode);
3175 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3176 0x7FFFFFFF, 0xFFFFFFFF);
3177 rtx sign_mask = gen_reg_rtx (V4SImode);
3178 rtx nan_mask = gen_reg_rtx (V4SImode);
3179 rtx hihi_promote = gen_reg_rtx (TImode);
3181 emit_move_insn (sign_mask, pat);
3182 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3184 emit_move_insn (nan_mask, pat);
3185 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3186 0x08090A0B, 0x18191A1B);
3187 emit_move_insn (hihi_promote, pat);
3189 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3190 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3192 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3193 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3194 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3195 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3196 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3197 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3199 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3200 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3201 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3202 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3203 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3205 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3206 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3207 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3208 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3213 (define_expand "cmeq_v2df"
3214 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3215 (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3216 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3219 if (spu_arch == PROCESSOR_CELL)
3221 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3222 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3223 rtx temp = gen_reg_rtx (TImode);
3224 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3225 rtx temp2 = gen_reg_rtx (V4SImode);
3226 rtx biteq = gen_reg_rtx (V4SImode);
3227 rtx ahi_inf = gen_reg_rtx (V4SImode);
3228 rtx a_nan = gen_reg_rtx (V4SImode);
3229 rtx a_abs = gen_reg_rtx (V4SImode);
3230 rtx b_abs = gen_reg_rtx (V4SImode);
3232 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3233 0x7FFFFFFF, 0xFFFFFFFF);
3234 rtx sign_mask = gen_reg_rtx (V4SImode);
3235 rtx nan_mask = gen_reg_rtx (V4SImode);
3236 rtx hihi_promote = gen_reg_rtx (TImode);
3238 emit_move_insn (sign_mask, pat);
3240 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3242 emit_move_insn (nan_mask, pat);
3243 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3244 0x08090A0B, 0x18191A1B);
3245 emit_move_insn (hihi_promote, pat);
3247 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3248 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3249 emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3250 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3252 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3253 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3254 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3255 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3257 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3258 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3259 emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3260 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3268 (define_insn "cgt_<mode>"
3269 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3270 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3271 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3275 cgt<bh>i\t%0,%1,%2")
3277 (define_insn "cgt_di_m1"
3278 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3279 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3284 (define_insn_and_split "cgt_di"
3285 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3286 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3287 (match_operand:DI 2 "spu_reg_operand" "r")))
3288 (clobber (match_scratch:V4SI 3 "=&r"))
3289 (clobber (match_scratch:V4SI 4 "=&r"))
3290 (clobber (match_scratch:V4SI 5 "=&r"))]
3294 [(set (match_dup:SI 0)
3295 (gt:SI (match_dup:DI 1)
3298 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3299 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3300 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3301 rtx op3 = operands[3];
3302 rtx op4 = operands[4];
3303 rtx op5 = operands[5];
3304 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3305 emit_insn (gen_clgt_v4si (op3, op1, op2));
3306 emit_insn (gen_ceq_v4si (op4, op1, op2));
3307 emit_insn (gen_cgt_v4si (op5, op1, op2));
3308 emit_insn (gen_spu_xswd (op3d, op3));
3309 emit_insn (gen_selb (op0, op5, op3, op4));
3313 (define_insn "cgt_ti_m1"
3314 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3315 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3320 (define_insn "cgt_ti"
3321 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3322 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3323 (match_operand:TI 2 "spu_reg_operand" "r")))
3324 (clobber (match_scratch:V4SI 3 "=&r"))
3325 (clobber (match_scratch:V4SI 4 "=&r"))
3326 (clobber (match_scratch:V4SI 5 "=&r"))]
3332 selb\t%0,%4,%0,%3\;\
3334 selb\t%0,%4,%0,%3\;\
3337 [(set_attr "type" "multi0")
3338 (set_attr "length" "36")])
3340 (define_insn "cgt_<mode>"
3341 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3342 (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3343 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3347 (define_insn "cmgt_<mode>"
3348 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3349 (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3350 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3354 (define_expand "cgt_df"
3355 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3356 (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3357 (match_operand:DF 2 "const_zero_operand" "i")))]
3360 if (spu_arch == PROCESSOR_CELL)
3362 rtx ra = gen_reg_rtx (V4SImode);
3363 rtx rb = gen_reg_rtx (V4SImode);
3364 rtx zero = gen_reg_rtx (V4SImode);
3365 rtx temp = gen_reg_rtx (TImode);
3366 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3367 rtx temp2 = gen_reg_rtx (V4SImode);
3368 rtx hi_inf = gen_reg_rtx (V4SImode);
3369 rtx a_nan = gen_reg_rtx (V4SImode);
3370 rtx b_nan = gen_reg_rtx (V4SImode);
3371 rtx a_abs = gen_reg_rtx (V4SImode);
3372 rtx b_abs = gen_reg_rtx (V4SImode);
3373 rtx asel = gen_reg_rtx (V4SImode);
3374 rtx bsel = gen_reg_rtx (V4SImode);
3375 rtx abor = gen_reg_rtx (V4SImode);
3376 rtx bbor = gen_reg_rtx (V4SImode);
3377 rtx gt_hi = gen_reg_rtx (V4SImode);
3378 rtx gt_lo = gen_reg_rtx (V4SImode);
3379 rtx sign_mask = gen_reg_rtx (V4SImode);
3380 rtx nan_mask = gen_reg_rtx (V4SImode);
3381 rtx hi_promote = gen_reg_rtx (TImode);
3382 rtx borrow_shuffle = gen_reg_rtx (TImode);
3384 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3385 0x7FFFFFFF, 0xFFFFFFFF);
3386 emit_move_insn (sign_mask, pat);
3387 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3389 emit_move_insn (nan_mask, pat);
3390 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3391 0x08090A0B, 0x08090A0B);
3392 emit_move_insn (hi_promote, pat);
3393 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3394 0x0C0D0E0F, 0xC0C0C0C0);
3395 emit_move_insn (borrow_shuffle, pat);
3397 emit_insn (gen_spu_convert (ra, operands[1]));
3398 emit_insn (gen_spu_convert (rb, operands[2]));
3399 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3400 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3402 if (!flag_finite_math_only)
3404 /* check if ra is NaN */
3405 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3406 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3407 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3409 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3410 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3411 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3413 /* check if rb is NaN */
3414 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3415 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3416 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3418 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3419 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3420 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3422 /* check if ra or rb is NaN */
3423 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3425 emit_move_insn (zero, CONST0_RTX (V4SImode));
3426 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3427 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3428 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3429 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3430 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3431 emit_insn (gen_selb (abor, a_abs, abor, asel));
3433 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3434 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3435 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3436 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3437 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3438 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3440 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3441 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3442 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3443 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3445 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3446 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3447 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3448 if (!flag_finite_math_only)
3450 /* correct for NaNs */
3451 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3453 emit_insn (gen_spu_convert (operands[0], temp2));
3458 (define_insn "cgt_<mode>_celledp"
3459 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3460 (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3461 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3462 "spu_arch == PROCESSOR_CELLEDP"
3464 [(set_attr "type" "fpd")])
3466 (define_insn "cmgt_<mode>_celledp"
3467 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3468 (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3469 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3470 "spu_arch == PROCESSOR_CELLEDP"
3472 [(set_attr "type" "fpd")])
3474 (define_expand "cgt_v2df"
3475 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3476 (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3477 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3480 if (spu_arch == PROCESSOR_CELL)
3482 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3483 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3484 rtx zero = gen_reg_rtx (V4SImode);
3485 rtx temp = gen_reg_rtx (TImode);
3486 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3487 rtx temp2 = gen_reg_rtx (V4SImode);
3488 rtx hi_inf = gen_reg_rtx (V4SImode);
3489 rtx a_nan = gen_reg_rtx (V4SImode);
3490 rtx b_nan = gen_reg_rtx (V4SImode);
3491 rtx a_abs = gen_reg_rtx (V4SImode);
3492 rtx b_abs = gen_reg_rtx (V4SImode);
3493 rtx asel = gen_reg_rtx (V4SImode);
3494 rtx bsel = gen_reg_rtx (V4SImode);
3495 rtx abor = gen_reg_rtx (V4SImode);
3496 rtx bbor = gen_reg_rtx (V4SImode);
3497 rtx gt_hi = gen_reg_rtx (V4SImode);
3498 rtx gt_lo = gen_reg_rtx (V4SImode);
3499 rtx sign_mask = gen_reg_rtx (V4SImode);
3500 rtx nan_mask = gen_reg_rtx (V4SImode);
3501 rtx hi_promote = gen_reg_rtx (TImode);
3502 rtx borrow_shuffle = gen_reg_rtx (TImode);
3503 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3504 0x7FFFFFFF, 0xFFFFFFFF);
3505 emit_move_insn (sign_mask, pat);
3506 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3508 emit_move_insn (nan_mask, pat);
3509 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3510 0x08090A0B, 0x08090A0B);
3511 emit_move_insn (hi_promote, pat);
3512 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3513 0x0C0D0E0F, 0xC0C0C0C0);
3514 emit_move_insn (borrow_shuffle, pat);
3516 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3517 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3518 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3519 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3521 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3522 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3523 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3524 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3525 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3526 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3527 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3529 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3530 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3531 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3532 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3533 emit_move_insn (zero, CONST0_RTX (V4SImode));
3534 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3535 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3536 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3537 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3538 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3539 emit_insn (gen_selb (abor, a_abs, abor, asel));
3540 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3541 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3542 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3543 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3544 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3545 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3546 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3547 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3548 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3549 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3551 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3552 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3554 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3555 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3556 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3561 (define_expand "cmgt_v2df"
3562 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3563 (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3564 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3567 if (spu_arch == PROCESSOR_CELL)
3569 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3570 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3571 rtx temp = gen_reg_rtx (TImode);
3572 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3573 rtx temp2 = gen_reg_rtx (V4SImode);
3574 rtx hi_inf = gen_reg_rtx (V4SImode);
3575 rtx a_nan = gen_reg_rtx (V4SImode);
3576 rtx b_nan = gen_reg_rtx (V4SImode);
3577 rtx a_abs = gen_reg_rtx (V4SImode);
3578 rtx b_abs = gen_reg_rtx (V4SImode);
3579 rtx gt_hi = gen_reg_rtx (V4SImode);
3580 rtx gt_lo = gen_reg_rtx (V4SImode);
3581 rtx sign_mask = gen_reg_rtx (V4SImode);
3582 rtx nan_mask = gen_reg_rtx (V4SImode);
3583 rtx hi_promote = gen_reg_rtx (TImode);
3584 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3585 0x7FFFFFFF, 0xFFFFFFFF);
3586 emit_move_insn (sign_mask, pat);
3587 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3589 emit_move_insn (nan_mask, pat);
3590 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3591 0x08090A0B, 0x08090A0B);
3592 emit_move_insn (hi_promote, pat);
3594 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3595 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3596 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3597 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3599 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3600 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3601 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3602 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3603 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3604 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3605 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3607 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3608 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3609 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3610 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3612 emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3613 emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3614 emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3615 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3617 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3618 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3619 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3620 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3621 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3629 (define_insn "clgt_<mode>"
3630 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3631 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3632 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3636 clgt<bh>i\t%0,%1,%2")
3638 (define_insn_and_split "clgt_di"
3639 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3640 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3641 (match_operand:DI 2 "spu_reg_operand" "r")))
3642 (clobber (match_scratch:V4SI 3 "=&r"))
3643 (clobber (match_scratch:V4SI 4 "=&r"))
3644 (clobber (match_scratch:V4SI 5 "=&r"))]
3648 [(set (match_dup:SI 0)
3649 (gtu:SI (match_dup:DI 1)
3652 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3653 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3654 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3655 rtx op3 = operands[3];
3656 rtx op4 = operands[4];
3657 rtx op5 = operands[5];
3658 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3659 emit_insn (gen_clgt_v4si (op3, op1, op2));
3660 emit_insn (gen_ceq_v4si (op4, op1, op2));
3661 emit_insn (gen_spu_xswd (op5d, op3));
3662 emit_insn (gen_selb (op0, op3, op5, op4));
3666 (define_insn "clgt_ti"
3667 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3668 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3669 (match_operand:TI 2 "spu_reg_operand" "r")))
3670 (clobber (match_scratch:V4SI 3 "=&r"))
3671 (clobber (match_scratch:V4SI 4 "=&r"))]
3676 selb\t%0,%4,%0,%3\;\
3678 selb\t%0,%4,%0,%3\;\
3681 [(set_attr "type" "multi0")
3682 (set_attr "length" "32")])
3686 (define_insn "dftsv_celledp"
3687 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3688 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3689 (match_operand:SI 2 "const_int_operand" "i")]
3691 "spu_arch == PROCESSOR_CELLEDP"
3693 [(set_attr "type" "fpd")])
3695 (define_expand "dftsv"
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")]
3702 if (spu_arch == PROCESSOR_CELL)
3704 rtx result = gen_reg_rtx (V4SImode);
3705 emit_move_insn (result, CONST0_RTX (V4SImode));
3707 if (INTVAL (operands[2]))
3709 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3710 rtx abs = gen_reg_rtx (V4SImode);
3711 rtx sign = gen_reg_rtx (V4SImode);
3712 rtx temp = gen_reg_rtx (TImode);
3713 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3714 rtx temp2 = gen_reg_rtx (V4SImode);
3715 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3716 0x7FFFFFFF, 0xFFFFFFFF);
3717 rtx sign_mask = gen_reg_rtx (V4SImode);
3718 rtx hi_promote = gen_reg_rtx (TImode);
3719 emit_move_insn (sign_mask, pat);
3720 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3721 0x08090A0B, 0x08090A0B);
3722 emit_move_insn (hi_promote, pat);
3724 emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3725 emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3726 emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3728 /* NaN or +inf or -inf */
3729 if (INTVAL (operands[2]) & 0x70)
3731 rtx nan_mask = gen_reg_rtx (V4SImode);
3732 rtx isinf = gen_reg_rtx (V4SImode);
3733 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3735 emit_move_insn (nan_mask, pat);
3736 emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3739 if (INTVAL (operands[2]) & 0x40)
3741 rtx isnan = gen_reg_rtx (V4SImode);
3742 emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3743 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3745 emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3746 emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3747 emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3748 emit_insn (gen_iorv4si3 (result, result, isnan));
3751 if (INTVAL (operands[2]) & 0x30)
3753 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3755 emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3756 emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3759 if (INTVAL (operands[2]) & 0x20)
3761 emit_insn (gen_andc_v4si (temp2, isinf, sign));
3762 emit_insn (gen_iorv4si3 (result, result, temp2));
3765 if (INTVAL (operands[2]) & 0x10)
3767 emit_insn (gen_andv4si3 (temp2, isinf, sign));
3768 emit_insn (gen_iorv4si3 (result, result, temp2));
3774 if (INTVAL (operands[2]) & 0xF)
3776 rtx iszero = gen_reg_rtx (V4SImode);
3777 emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3778 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3780 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3783 if (INTVAL (operands[2]) & 0x3)
3785 rtx isdenorm = gen_reg_rtx (V4SImode);
3786 rtx denorm_mask = gen_reg_rtx (V4SImode);
3787 emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3788 emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3789 emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3790 emit_insn (gen_shufb (isdenorm, isdenorm,
3791 isdenorm, hi_promote));
3793 if (INTVAL (operands[2]) & 0x2)
3795 emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3796 emit_insn (gen_iorv4si3 (result, result, temp2));
3799 if (INTVAL (operands[2]) & 0x1)
3801 emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3802 emit_insn (gen_iorv4si3 (result, result, temp2));
3807 if (INTVAL (operands[2]) & 0xC)
3809 emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3811 if (INTVAL (operands[2]) & 0x8)
3813 emit_insn (gen_andc_v4si (temp2, iszero, sign));
3814 emit_insn (gen_iorv4si3 (result, result, temp2));
3817 if (INTVAL (operands[2]) & 0x4)
3819 emit_insn (gen_andv4si3 (temp2, iszero, sign));
3820 emit_insn (gen_iorv4si3 (result, result, temp2));
3825 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3835 (if_then_else (match_operator 1 "branch_comparison_operator"
3837 "spu_reg_operand" "r")
3839 (label_ref (match_operand 0 "" ""))
3843 [(set_attr "type" "br")])
3847 (if_then_else (match_operator 0 "branch_comparison_operator"
3849 "spu_reg_operand" "r")
3855 [(set_attr "type" "br")])
3859 (if_then_else (match_operator 1 "branch_comparison_operator"
3861 "spu_reg_operand" "r")
3864 (label_ref (match_operand 0 "" ""))))]
3867 [(set_attr "type" "br")])
3871 (if_then_else (match_operator 0 "branch_comparison_operator"
3873 "spu_reg_operand" "r")
3879 [(set_attr "type" "br")])
3882 ;; vector conditional compare patterns
3883 (define_expand "vcond<mode><mode>"
3884 [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3886 (match_operator 3 "comparison_operator"
3887 [(match_operand:VCMP 4 "spu_reg_operand" "r")
3888 (match_operand:VCMP 5 "spu_reg_operand" "r")])
3889 (match_operand:VCMP 1 "spu_reg_operand" "r")
3890 (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3893 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3894 operands[3], operands[4], operands[5]))
3900 (define_expand "vcondu<mode><mode>"
3901 [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3903 (match_operator 3 "comparison_operator"
3904 [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3905 (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3906 (match_operand:VCMPU 1 "spu_reg_operand" "r")
3907 (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3910 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3911 operands[3], operands[4], operands[5]))
3918 ;; branch on condition
3920 (define_expand "cbranch<mode>4"
3921 [(use (match_operator 0 "ordered_comparison_operator"
3922 [(match_operand:VQHSI 1 "spu_reg_operand" "")
3923 (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3924 (use (match_operand 3 ""))]
3926 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3928 (define_expand "cbranch<mode>4"
3929 [(use (match_operator 0 "ordered_comparison_operator"
3930 [(match_operand:DTI 1 "spu_reg_operand" "")
3931 (match_operand:DTI 2 "spu_reg_operand" "")]))
3932 (use (match_operand 3 ""))]
3934 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3936 (define_expand "cbranch<mode>4"
3937 [(use (match_operator 0 "ordered_comparison_operator"
3938 [(match_operand:VSF 1 "spu_reg_operand" "")
3939 (match_operand:VSF 2 "spu_reg_operand" "")]))
3940 (use (match_operand 3 ""))]
3942 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3944 (define_expand "cbranchdf4"
3945 [(use (match_operator 0 "ordered_comparison_operator"
3946 [(match_operand:DF 1 "spu_reg_operand" "")
3947 (match_operand:DF 2 "spu_reg_operand" "")]))
3948 (use (match_operand 3 ""))]
3950 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3955 (define_expand "cstore<mode>4"
3956 [(use (match_operator 1 "ordered_comparison_operator"
3957 [(match_operand:VQHSI 2 "spu_reg_operand" "")
3958 (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3959 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3961 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3963 (define_expand "cstore<mode>4"
3964 [(use (match_operator 1 "ordered_comparison_operator"
3965 [(match_operand:DTI 2 "spu_reg_operand" "")
3966 (match_operand:DTI 3 "spu_reg_operand" "")]))
3967 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3969 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3971 (define_expand "cstore<mode>4"
3972 [(use (match_operator 1 "ordered_comparison_operator"
3973 [(match_operand:VSF 2 "spu_reg_operand" "")
3974 (match_operand:VSF 3 "spu_reg_operand" "")]))
3975 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3977 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3979 (define_expand "cstoredf4"
3980 [(use (match_operator 1 "ordered_comparison_operator"
3981 [(match_operand:DF 2 "spu_reg_operand" "")
3982 (match_operand:DF 3 "spu_reg_operand" "")]))
3983 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3985 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3990 ;; Define this first one so HAVE_conditional_move is defined.
3991 (define_insn "movcc_dummy"
3992 [(set (match_operand 0 "" "")
3993 (if_then_else (match_operand 1 "" "")
3994 (match_operand 2 "" "")
3995 (match_operand 3 "" "")))]
3999 (define_expand "mov<mode>cc"
4000 [(set (match_operand:ALL 0 "spu_reg_operand" "")
4001 (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
4002 (match_operand:ALL 2 "spu_reg_operand" "")
4003 (match_operand:ALL 3 "spu_reg_operand" "")))]
4006 spu_emit_branch_or_set(2, operands[1], operands);
4010 ;; This pattern is used when the result of a compare is not large
4011 ;; enough to use in a selb when expanding conditional moves.
4012 (define_expand "extend_compare"
4013 [(set (match_operand 0 "spu_reg_operand" "=r")
4014 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4017 emit_insn (gen_rtx_SET (operands[0],
4018 gen_rtx_UNSPEC (GET_MODE (operands[0]),
4019 gen_rtvec (1, operands[1]),
4020 UNSPEC_EXTEND_CMP)));
4024 (define_insn "extend_compare<mode>"
4025 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
4026 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4029 [(set_attr "type" "shuf")])
4034 ;; operand 0 is index
4035 ;; operand 1 is the minimum bound
4036 ;; operand 2 is the maximum bound - minimum bound + 1
4037 ;; operand 3 is CODE_LABEL for the table;
4038 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4039 (define_expand "casesi"
4040 [(match_operand:SI 0 "spu_reg_operand" "")
4041 (match_operand:SI 1 "immediate_operand" "")
4042 (match_operand:SI 2 "immediate_operand" "")
4043 (match_operand 3 "" "")
4044 (match_operand 4 "" "")]
4047 rtx table = gen_reg_rtx (SImode);
4048 rtx index = gen_reg_rtx (SImode);
4049 rtx sindex = gen_reg_rtx (SImode);
4050 rtx addr = gen_reg_rtx (Pmode);
4052 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
4054 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
4055 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
4056 emit_move_insn (addr, gen_rtx_MEM (SImode,
4057 gen_rtx_PLUS (SImode, table, sindex)));
4059 emit_insn (gen_addsi3 (addr, addr, table));
4061 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
4062 emit_jump_insn (gen_tablejump (addr, operands[3]));
4066 (define_insn "tablejump"
4067 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
4068 (use (label_ref (match_operand 1 "" "")))]
4071 [(set_attr "type" "br")])
4076 ;; Note that operand 1 is total size of args, in bytes,
4077 ;; and what the call insn wants is the number of words.
4078 (define_expand "sibcall"
4080 [(call (match_operand:QI 0 "call_operand" "")
4081 (match_operand:QI 1 "" ""))
4085 if (! call_operand (operands[0], QImode))
4086 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4089 (define_insn "_sibcall"
4091 [(call (match_operand:QI 0 "call_operand" "R,S")
4092 (match_operand:QI 1 "" "i,i"))
4094 "SIBLING_CALL_P(insn)"
4098 [(set_attr "type" "br,br")])
4100 (define_expand "sibcall_value"
4102 [(set (match_operand 0 "" "")
4103 (call (match_operand:QI 1 "call_operand" "")
4104 (match_operand:QI 2 "" "")))
4108 if (! call_operand (operands[1], QImode))
4109 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4112 (define_insn "_sibcall_value"
4114 [(set (match_operand 0 "" "")
4115 (call (match_operand:QI 1 "call_operand" "R,S")
4116 (match_operand:QI 2 "" "i,i")))
4118 "SIBLING_CALL_P(insn)"
4122 [(set_attr "type" "br,br")])
4124 ;; Note that operand 1 is total size of args, in bytes,
4125 ;; and what the call insn wants is the number of words.
4126 (define_expand "call"
4128 [(call (match_operand:QI 0 "call_operand" "")
4129 (match_operand:QI 1 "" ""))
4130 (clobber (reg:SI 0))
4131 (clobber (reg:SI 130))])]
4134 if (! call_operand (operands[0], QImode))
4135 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4138 (define_insn "_call"
4140 [(call (match_operand:QI 0 "call_operand" "R,S,T")
4141 (match_operand:QI 1 "" "i,i,i"))
4142 (clobber (reg:SI 0))
4143 (clobber (reg:SI 130))])]
4149 [(set_attr "type" "br")])
4151 (define_expand "call_value"
4153 [(set (match_operand 0 "" "")
4154 (call (match_operand:QI 1 "call_operand" "")
4155 (match_operand:QI 2 "" "")))
4156 (clobber (reg:SI 0))
4157 (clobber (reg:SI 130))])]
4160 if (! call_operand (operands[1], QImode))
4161 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4164 (define_insn "_call_value"
4166 [(set (match_operand 0 "" "")
4167 (call (match_operand:QI 1 "call_operand" "R,S,T")
4168 (match_operand:QI 2 "" "i,i,i")))
4169 (clobber (reg:SI 0))
4170 (clobber (reg:SI 130))])]
4176 [(set_attr "type" "br")])
4178 (define_expand "untyped_call"
4179 [(parallel [(call (match_operand 0 "" "")
4181 (match_operand 1 "" "")
4182 (match_operand 2 "" "")])]
4186 rtx reg = gen_rtx_REG (TImode, 3);
4188 /* We need to use call_value so the return value registers don't get
4190 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4192 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4194 rtx set = XVECEXP (operands[2], 0, i);
4195 emit_move_insn (SET_DEST (set), SET_SRC (set));
4198 /* The optimizer does not know that the call sets the function value
4199 registers we stored in the result block. We avoid problems by
4200 claiming that all hard registers are used and clobbered at this
4202 emit_insn (gen_blockage ());
4208 ;; Patterns used for splitting and combining.
4211 ;; Function prologue and epilogue.
4213 (define_expand "prologue"
4216 { spu_expand_prologue (); DONE; })
4218 ;; "blockage" is only emitted in epilogue. This is what it took to
4219 ;; make "basic block reordering" work with the insns sequence
4220 ;; generated by the spu_expand_epilogue (taken from mips.md)
4222 (define_insn "blockage"
4223 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
4226 [(set_attr "type" "convert")
4227 (set_attr "length" "0")])
4229 (define_expand "epilogue"
4232 { spu_expand_epilogue (false); DONE; })
4234 (define_expand "sibcall_epilogue"
4237 { spu_expand_epilogue (true); DONE; })
4240 ;; stack manipulations
4242 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4243 ;; We move the back-chain and decrement the stack pointer.
4244 (define_expand "allocate_stack"
4245 [(set (match_operand 0 "spu_reg_operand" "")
4246 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4248 (minus (reg 1) (match_dup 1)))]
4250 "spu_allocate_stack (operands[0], operands[1]); DONE;")
4252 ;; These patterns say how to save and restore the stack pointer. We need not
4253 ;; save the stack pointer at function level since we are careful to preserve
4257 ;; At block level the stack pointer is saved and restored, so that the
4258 ;; stack space allocated within a block is deallocated when leaving
4259 ;; block scope. By default, according to the SPU ABI, the stack
4260 ;; pointer and available stack size are saved in a register. Upon
4261 ;; restoration, the stack pointer is simply copied back, and the
4262 ;; current available stack size is calculated against the restored
4265 ;; For nonlocal gotos, we must save the stack pointer and its
4266 ;; backchain and restore both. Note that in the nonlocal case, the
4267 ;; save area is a memory location.
4269 (define_expand "save_stack_function"
4270 [(match_operand 0 "general_operand" "")
4271 (match_operand 1 "general_operand" "")]
4275 (define_expand "restore_stack_function"
4276 [(match_operand 0 "general_operand" "")
4277 (match_operand 1 "general_operand" "")]
4281 (define_expand "restore_stack_block"
4282 [(match_operand 0 "spu_reg_operand" "")
4283 (match_operand 1 "memory_operand" "")]
4287 spu_restore_stack_block (operands[0], operands[1]);
4291 (define_expand "save_stack_nonlocal"
4292 [(match_operand 0 "memory_operand" "")
4293 (match_operand 1 "spu_reg_operand" "")]
4297 rtx temp = gen_reg_rtx (Pmode);
4299 /* Copy the backchain to the first word, sp to the second. We need to
4300 save the back chain because __builtin_apply appears to clobber it. */
4301 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4302 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4303 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4307 (define_expand "restore_stack_nonlocal"
4308 [(match_operand 0 "spu_reg_operand" "")
4309 (match_operand 1 "memory_operand" "")]
4313 spu_restore_stack_nonlocal(operands[0], operands[1]);
4320 ;; Vector initialization
4321 (define_expand "vec_init<mode>"
4322 [(match_operand:V 0 "register_operand" "")
4323 (match_operand 1 "" "")]
4326 spu_expand_vector_init (operands[0], operands[1]);
4330 (define_expand "vec_set<mode>"
4331 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4332 (set (match_dup:TI 3)
4333 (unspec:TI [(match_dup:SI 4)
4335 (match_dup:SI 6)] UNSPEC_CPAT))
4336 (set (match_operand:V 0 "spu_reg_operand" "")
4337 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4339 (match_dup:TI 3)] UNSPEC_SHUFB))]
4342 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4343 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4344 operands[3] = gen_reg_rtx (TImode);
4345 operands[4] = stack_pointer_rtx;
4346 operands[5] = offset;
4347 operands[6] = GEN_INT (size);
4350 (define_expand "vec_extract<mode>"
4351 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4352 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4353 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4356 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4358 emit_insn (gen_spu_convert (operands[0], operands[1]));
4363 (define_insn "_vec_extract<mode>"
4364 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4365 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4366 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4368 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4369 [(set_attr "type" "shuf")])
4371 (define_insn "_vec_extractv8hi_ze"
4372 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4373 (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4374 (parallel [(const_int 0)]))))]
4376 "rotqmbyi\t%0,%1,-2"
4377 [(set_attr "type" "shuf")])
4382 (define_expand "shufb"
4383 [(set (match_operand 0 "spu_reg_operand" "")
4384 (unspec [(match_operand 1 "spu_reg_operand" "")
4385 (match_operand 2 "spu_reg_operand" "")
4386 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4389 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4390 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4395 (define_insn "_shufb"
4396 [(set (match_operand 0 "spu_reg_operand" "=r")
4397 (unspec [(match_operand 1 "spu_reg_operand" "r")
4398 (match_operand 2 "spu_reg_operand" "r")
4399 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4401 "shufb\t%0,%1,%2,%3"
4402 [(set_attr "type" "shuf")])
4404 ; The semantics of vec_permv16qi are nearly identical to those of the SPU
4405 ; shufb instruction, except that we need to reduce the selector modulo 32.
4406 (define_expand "vec_permv16qi"
4407 [(set (match_dup 4) (and:V16QI (match_operand:V16QI 3 "spu_reg_operand" "")
4409 (set (match_operand:V16QI 0 "spu_reg_operand" "")
4411 [(match_operand:V16QI 1 "spu_reg_operand" "")
4412 (match_operand:V16QI 2 "spu_reg_operand" "")
4417 operands[4] = gen_reg_rtx (V16QImode);
4418 operands[5] = gen_lowpart (TImode, operands[4]);
4419 operands[6] = spu_const (V16QImode, 31);
4423 [(unspec_volatile [(const_int 0)] UNSPECV_NOP)]
4426 [(set_attr "type" "nop")])
4429 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPECV_NOP)]
4432 [(set_attr "type" "nop")])
4435 [(unspec_volatile [(const_int 0)] UNSPECV_LNOP)]
4438 [(set_attr "type" "lnop")])
4440 ;; The operand is so we know why we generated this hbrp.
4441 ;; We clobber mem to make sure it isn't moved over any
4442 ;; loads, stores or calls while scheduling.
4443 (define_insn "iprefetch"
4444 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4445 (clobber (mem:BLK (scratch)))]
4448 [(set_attr "type" "iprefetch")])
4450 ;; A non-volatile version so it gets scheduled
4451 (define_insn "nopn_nv"
4452 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4455 [(set_attr "type" "nop")])
4459 (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4460 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4461 (unspec [(const_int 0)] UNSPEC_HBR)]
4467 [(set_attr "type" "hbr")])
4470 [(unspec_volatile [(const_int 0)] UNSPECV_SYNC)
4471 (clobber (mem:BLK (scratch)))]
4474 [(set_attr "type" "br")])
4476 (define_insn "syncc"
4477 [(unspec_volatile [(const_int 1)] UNSPECV_SYNC)
4478 (clobber (mem:BLK (scratch)))]
4481 [(set_attr "type" "br")])
4483 (define_insn "dsync"
4484 [(unspec_volatile [(const_int 2)] UNSPECV_SYNC)
4485 (clobber (mem:BLK (scratch)))]
4488 [(set_attr "type" "br")])
4492 ;; Define the subtract-one-and-jump insns so loop.c
4493 ;; knows what to generate.
4494 (define_expand "doloop_end"
4495 [(use (match_operand 0 "" "")) ; loop pseudo
4496 (use (match_operand 1 "" ""))] ; label
4500 /* Currently SMS relies on the do-loop pattern to recognize loops
4501 where (1) the control part comprises of all insns defining and/or
4502 using a certain 'count' register and (2) the loop count can be
4503 adjusted by modifying this register prior to the loop.
4504 . ??? The possible introduction of a new block to initialize the
4505 new IV can potentially effects branch optimizations. */
4506 if (optimize > 0 && flag_modulo_sched)
4512 if (GET_MODE (operands[0]) != SImode)
4516 emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4517 bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4518 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4519 emit_jump_insn (gen_rtx_SET (pc_rtx,
4520 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4528 ;; convert between any two modes, avoiding any GCC assumptions
4529 (define_expand "spu_convert"
4530 [(set (match_operand 0 "spu_reg_operand" "")
4531 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4534 rtx c = gen__spu_convert (operands[0], operands[1]);
4535 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4540 (define_insn_and_split "_spu_convert"
4541 [(set (match_operand 0 "spu_reg_operand" "=r")
4542 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4548 spu_split_convert (operands);
4551 [(set_attr "type" "convert")
4552 (set_attr "length" "0")])
4556 (include "spu-builtins.md")
4559 (define_expand "smaxv4sf3"
4560 [(set (match_operand:V4SF 0 "register_operand" "=r")
4561 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4562 (match_operand:V4SF 2 "register_operand" "r")))]
4566 rtx mask = gen_reg_rtx (V4SImode);
4568 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4569 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4573 (define_expand "sminv4sf3"
4574 [(set (match_operand:V4SF 0 "register_operand" "=r")
4575 (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4576 (match_operand:V4SF 2 "register_operand" "r")))]
4580 rtx mask = gen_reg_rtx (V4SImode);
4582 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4583 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4587 (define_expand "smaxv2df3"
4588 [(set (match_operand:V2DF 0 "register_operand" "=r")
4589 (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4590 (match_operand:V2DF 2 "register_operand" "r")))]
4594 rtx mask = gen_reg_rtx (V2DImode);
4595 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4596 emit_insn (gen_selb (operands[0], operands[2], operands[1],
4597 spu_gen_subreg (V4SImode, mask)));
4601 (define_expand "sminv2df3"
4602 [(set (match_operand:V2DF 0 "register_operand" "=r")
4603 (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4604 (match_operand:V2DF 2 "register_operand" "r")))]
4608 rtx mask = gen_reg_rtx (V2DImode);
4609 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4610 emit_insn (gen_selb (operands[0], operands[1], operands[2],
4611 spu_gen_subreg (V4SImode, mask)));
4615 (define_insn "vec_widen_smult_odd_v8hi"
4616 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
4620 (match_operand:V8HI 1 "spu_reg_operand" "r,r")
4621 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
4624 (match_operand:V8HI 2 "spu_arith_operand" "r,B")
4625 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
4630 [(set_attr "type" "fp7")])
4632 (define_insn "vec_widen_umult_odd_v8hi"
4633 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
4637 (match_operand:V8HI 1 "spu_reg_operand" "r,r")
4638 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
4641 (match_operand:V8HI 2 "spu_arith_operand" "r,B")
4642 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
4647 [(set_attr "type" "fp7")])
4649 (define_insn "vec_widen_smult_even_v8hi"
4650 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4654 (match_operand:V8HI 1 "spu_reg_operand" "r")
4655 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
4658 (match_operand:V8HI 2 "spu_reg_operand" "r")
4659 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
4662 [(set_attr "type" "fp7")])
4664 (define_insn "vec_widen_umult_even_v8hi"
4665 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4669 (match_operand:V8HI 1 "spu_reg_operand" "r")
4670 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
4673 (match_operand:V8HI 2 "spu_reg_operand" "r")
4674 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
4677 [(set_attr "type" "fp7")])
4679 (define_expand "vec_widen_umult_hi_v8hi"
4680 [(set (match_operand:V4SI 0 "register_operand" "=r")
4684 (match_operand:V8HI 1 "register_operand" "r")
4685 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4688 (match_operand:V8HI 2 "register_operand" "r")
4689 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4693 rtx ve = gen_reg_rtx (V4SImode);
4694 rtx vo = gen_reg_rtx (V4SImode);
4695 rtx mask = gen_reg_rtx (TImode);
4696 unsigned char arr[16] = {
4697 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4698 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4700 emit_move_insn (mask, array_to_constant (TImode, arr));
4701 emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
4702 emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
4703 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4707 (define_expand "vec_widen_umult_lo_v8hi"
4708 [(set (match_operand:V4SI 0 "register_operand" "=r")
4712 (match_operand:V8HI 1 "register_operand" "r")
4713 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4716 (match_operand:V8HI 2 "register_operand" "r")
4717 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4721 rtx ve = gen_reg_rtx (V4SImode);
4722 rtx vo = gen_reg_rtx (V4SImode);
4723 rtx mask = gen_reg_rtx (TImode);
4724 unsigned char arr[16] = {
4725 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4726 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4728 emit_move_insn (mask, array_to_constant (TImode, arr));
4729 emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
4730 emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
4731 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4735 (define_expand "vec_widen_smult_hi_v8hi"
4736 [(set (match_operand:V4SI 0 "register_operand" "=r")
4740 (match_operand:V8HI 1 "register_operand" "r")
4741 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4744 (match_operand:V8HI 2 "register_operand" "r")
4745 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4749 rtx ve = gen_reg_rtx (V4SImode);
4750 rtx vo = gen_reg_rtx (V4SImode);
4751 rtx mask = gen_reg_rtx (TImode);
4752 unsigned char arr[16] = {
4753 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4754 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4756 emit_move_insn (mask, array_to_constant (TImode, arr));
4757 emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
4758 emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
4759 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4763 (define_expand "vec_widen_smult_lo_v8hi"
4764 [(set (match_operand:V4SI 0 "register_operand" "=r")
4768 (match_operand:V8HI 1 "register_operand" "r")
4769 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4772 (match_operand:V8HI 2 "register_operand" "r")
4773 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4777 rtx ve = gen_reg_rtx (V4SImode);
4778 rtx vo = gen_reg_rtx (V4SImode);
4779 rtx mask = gen_reg_rtx (TImode);
4780 unsigned char arr[16] = {
4781 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4782 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4784 emit_move_insn (mask, array_to_constant (TImode, arr));
4785 emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
4786 emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
4787 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4791 (define_expand "vec_realign_load_<mode>"
4792 [(set (match_operand:ALL 0 "register_operand" "=r")
4793 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4794 (match_operand:ALL 2 "register_operand" "r")
4795 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4799 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4803 (define_expand "spu_lvsr"
4804 [(set (match_operand:V16QI 0 "register_operand" "")
4805 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4810 rtx offset = gen_reg_rtx (V8HImode);
4811 rtx addr_bits = gen_reg_rtx (SImode);
4812 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4813 rtx splatqi = gen_reg_rtx (TImode);
4814 rtx result = gen_reg_rtx (V8HImode);
4815 unsigned char arr[16] = {
4816 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4817 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4818 unsigned char arr2[16] = {
4819 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4820 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4822 emit_move_insn (offset, array_to_constant (V8HImode, arr));
4823 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4825 gcc_assert (GET_CODE (operands[1]) == MEM);
4826 addr = force_reg (Pmode, XEXP (operands[1], 0));
4827 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4828 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4830 /* offset - (addr & 0xF)
4831 It is safe to use a single sfh, because each byte of offset is > 15 and
4832 each byte of addr is <= 15. */
4833 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4835 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4836 emit_move_insn (operands[0], result);
4841 (define_expand "vec_unpacku_hi_v8hi"
4842 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4845 (match_operand:V8HI 1 "spu_reg_operand" "r")
4846 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4849 rtx mask = gen_reg_rtx (TImode);
4850 unsigned char arr[16] = {
4851 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4852 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4854 emit_move_insn (mask, array_to_constant (TImode, arr));
4855 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4860 (define_expand "vec_unpacku_lo_v8hi"
4861 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4864 (match_operand:V8HI 1 "spu_reg_operand" "r")
4865 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4868 rtx mask = gen_reg_rtx (TImode);
4869 unsigned char arr[16] = {
4870 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4871 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4873 emit_move_insn (mask, array_to_constant (TImode, arr));
4874 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4879 (define_expand "vec_unpacks_hi_v8hi"
4880 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4883 (match_operand:V8HI 1 "spu_reg_operand" "r")
4884 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4887 rtx tmp1 = gen_reg_rtx (V8HImode);
4888 rtx tmp2 = gen_reg_rtx (V4SImode);
4889 rtx mask = gen_reg_rtx (TImode);
4890 unsigned char arr[16] = {
4891 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4892 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4894 emit_move_insn (mask, array_to_constant (TImode, arr));
4895 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4896 emit_insn (gen_spu_xshw (tmp2, tmp1));
4897 emit_move_insn (operands[0], tmp2);
4902 (define_expand "vec_unpacks_lo_v8hi"
4903 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4906 (match_operand:V8HI 1 "spu_reg_operand" "r")
4907 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4910 rtx tmp1 = gen_reg_rtx (V8HImode);
4911 rtx tmp2 = gen_reg_rtx (V4SImode);
4912 rtx mask = gen_reg_rtx (TImode);
4913 unsigned char arr[16] = {
4914 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4915 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4917 emit_move_insn (mask, array_to_constant (TImode, arr));
4918 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4919 emit_insn (gen_spu_xshw (tmp2, tmp1));
4920 emit_move_insn (operands[0], tmp2);
4925 (define_expand "vec_unpacku_hi_v16qi"
4926 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4929 (match_operand:V16QI 1 "spu_reg_operand" "r")
4930 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4931 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4934 rtx mask = gen_reg_rtx (TImode);
4935 unsigned char arr[16] = {
4936 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4937 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4939 emit_move_insn (mask, array_to_constant (TImode, arr));
4940 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4945 (define_expand "vec_unpacku_lo_v16qi"
4946 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4949 (match_operand:V16QI 1 "spu_reg_operand" "r")
4950 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4951 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4954 rtx mask = gen_reg_rtx (TImode);
4955 unsigned char arr[16] = {
4956 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4957 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4959 emit_move_insn (mask, array_to_constant (TImode, arr));
4960 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4965 (define_expand "vec_unpacks_hi_v16qi"
4966 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4969 (match_operand:V16QI 1 "spu_reg_operand" "r")
4970 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4971 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4974 rtx tmp1 = gen_reg_rtx (V16QImode);
4975 rtx tmp2 = gen_reg_rtx (V8HImode);
4976 rtx mask = gen_reg_rtx (TImode);
4977 unsigned char arr[16] = {
4978 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4979 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4981 emit_move_insn (mask, array_to_constant (TImode, arr));
4982 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4983 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4984 emit_move_insn (operands[0], tmp2);
4989 (define_expand "vec_unpacks_lo_v16qi"
4990 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4993 (match_operand:V16QI 1 "spu_reg_operand" "r")
4994 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4995 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4998 rtx tmp1 = gen_reg_rtx (V16QImode);
4999 rtx tmp2 = gen_reg_rtx (V8HImode);
5000 rtx mask = gen_reg_rtx (TImode);
5001 unsigned char arr[16] = {
5002 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
5003 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
5005 emit_move_insn (mask, array_to_constant (TImode, arr));
5006 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
5007 emit_insn (gen_spu_xsbh (tmp2, tmp1));
5008 emit_move_insn (operands[0], tmp2);
5014 (define_expand "vec_pack_trunc_v8hi"
5015 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5017 (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5018 (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5022 rtx mask = gen_reg_rtx (TImode);
5023 unsigned char arr[16] = {
5024 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5025 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5027 emit_move_insn (mask, array_to_constant (TImode, arr));
5028 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5033 (define_expand "vec_pack_trunc_v4si"
5034 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5036 (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5037 (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5041 rtx mask = gen_reg_rtx (TImode);
5042 unsigned char arr[16] = {
5043 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5044 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5046 emit_move_insn (mask, array_to_constant (TImode, arr));
5047 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5052 (define_insn "stack_protect_set"
5053 [(set (match_operand:SI 0 "memory_operand" "=m")
5054 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5055 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5057 "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5058 [(set_attr "length" "12")
5059 (set_attr "type" "multi1")]
5062 (define_expand "stack_protect_test"
5063 [(match_operand 0 "memory_operand" "")
5064 (match_operand 1 "memory_operand" "")
5065 (match_operand 2 "" "")]
5071 compare_result = gen_reg_rtx (SImode);
5073 emit_insn (gen_stack_protect_test_si (compare_result,
5077 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5079 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5081 emit_jump_insn (gen_rtx_SET (pc_rtx,
5082 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5088 (define_insn "stack_protect_test_si"
5089 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5090 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5091 (match_operand:SI 2 "memory_operand" "m")]
5093 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5095 "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5096 [(set_attr "length" "16")
5097 (set_attr "type" "multi1")]
5102 ; SPU execution is always single-threaded, so there is no need for real
5103 ; atomic operations. We provide the atomic primitives anyway so that
5104 ; code expecting the builtins to be present (like libgfortran) will work.
5106 ;; Types that we should provide atomic instructions for.
5107 (define_mode_iterator AINT [QI HI SI DI TI])
5109 (define_code_iterator ATOMIC [plus minus ior xor and mult])
5110 (define_code_attr atomic_name
5111 [(plus "add") (minus "sub")
5112 (ior "or") (xor "xor") (and "and") (mult "nand")])
5113 (define_code_attr atomic_pred
5114 [(plus "spu_arith_operand") (minus "spu_reg_operand")
5115 (ior "spu_logical_operand") (xor "spu_logical_operand")
5116 (and "spu_logical_operand") (mult "spu_logical_operand")])
5118 (define_expand "atomic_load<mode>"
5119 [(set (match_operand:AINT 0 "spu_reg_operand" "") ;; output
5120 (match_operand:AINT 1 "memory_operand" "")) ;; memory
5121 (use (match_operand:SI 2 "const_int_operand" ""))] ;; model
5124 if (MEM_ADDR_SPACE (operands[1]))
5127 emit_move_insn (operands[0], operands[1]);
5131 (define_expand "atomic_store<mode>"
5132 [(set (match_operand:AINT 0 "memory_operand" "") ;; memory
5133 (match_operand:AINT 1 "spu_reg_operand" "")) ;; input
5134 (use (match_operand:SI 2 "const_int_operand" ""))] ;; model
5137 if (MEM_ADDR_SPACE (operands[0]))
5140 emit_move_insn (operands[0], operands[1]);
5144 (define_expand "atomic_compare_and_swap<mode>"
5145 [(match_operand:SI 0 "spu_reg_operand" "") ;; bool out
5146 (match_operand:AINT 1 "spu_reg_operand" "") ;; val out
5147 (match_operand:AINT 2 "memory_operand" "") ;; memory
5148 (match_operand:AINT 3 "spu_nonmem_operand" "") ;; expected
5149 (match_operand:AINT 4 "spu_nonmem_operand" "") ;; desired
5150 (match_operand:SI 5 "const_int_operand" "") ;; is_weak
5151 (match_operand:SI 6 "const_int_operand" "") ;; model succ
5152 (match_operand:SI 7 "const_int_operand" "")] ;; model fail
5155 rtx boolval, retval, label;
5157 if (MEM_ADDR_SPACE (operands[2]))
5160 boolval = gen_reg_rtx (SImode);
5161 retval = gen_reg_rtx (<MODE>mode);
5162 label = gen_label_rtx ();
5164 emit_move_insn (retval, operands[2]);
5165 emit_move_insn (boolval, const0_rtx);
5167 emit_cmp_and_jump_insns (retval, operands[3], NE, NULL_RTX,
5168 <MODE>mode, 1, label);
5170 emit_move_insn (operands[2], operands[4]);
5171 emit_move_insn (boolval, const1_rtx);
5175 emit_move_insn (operands[0], boolval);
5176 emit_move_insn (operands[1], retval);
5180 (define_expand "atomic_exchange<mode>"
5181 [(match_operand:AINT 0 "spu_reg_operand" "") ;; output
5182 (match_operand:AINT 1 "memory_operand" "") ;; memory
5183 (match_operand:AINT 2 "spu_nonmem_operand" "") ;; input
5184 (match_operand:SI 3 "const_int_operand" "")] ;; model
5189 if (MEM_ADDR_SPACE (operands[1]))
5192 retval = gen_reg_rtx (<MODE>mode);
5194 emit_move_insn (retval, operands[1]);
5195 emit_move_insn (operands[1], operands[2]);
5196 emit_move_insn (operands[0], retval);
5200 (define_expand "atomic_<atomic_name><mode>"
5202 (match_operand:AINT 0 "memory_operand" "") ;; memory
5203 (match_operand:AINT 1 "<atomic_pred>" "")) ;; operand
5204 (match_operand:SI 2 "const_int_operand" "")] ;; model
5207 if (MEM_ADDR_SPACE (operands[0]))
5210 spu_expand_atomic_op (<CODE>, operands[0], operands[1],
5211 NULL_RTX, NULL_RTX);
5215 (define_expand "atomic_fetch_<atomic_name><mode>"
5216 [(match_operand:AINT 0 "spu_reg_operand" "") ;; output
5218 (match_operand:AINT 1 "memory_operand" "") ;; memory
5219 (match_operand:AINT 2 "<atomic_pred>" "")) ;; operand
5220 (match_operand:SI 3 "const_int_operand" "")] ;; model
5223 if (MEM_ADDR_SPACE (operands[1]))
5226 spu_expand_atomic_op (<CODE>, operands[1], operands[2],
5227 operands[0], NULL_RTX);
5231 (define_expand "atomic_<atomic_name>_fetch<mode>"
5232 [(match_operand:AINT 0 "spu_reg_operand" "") ;; output
5234 (match_operand:AINT 1 "memory_operand" "") ;; memory
5235 (match_operand:AINT 2 "<atomic_pred>" "")) ;; operand
5236 (match_operand:SI 3 "const_int_operand" "")] ;; model
5239 if (MEM_ADDR_SPACE (operands[1]))
5242 spu_expand_atomic_op (<CODE>, operands[1], operands[2],
5243 NULL_RTX, operands[0]);