1 ;; Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3 ;; This file is free software; you can redistribute it and/or modify it under
4 ;; the terms of the GNU General Public License as published by the Free
5 ;; Software Foundation; either version 3 of the License, or (at your option)
8 ;; This file is distributed in the hope that it will be useful, but WITHOUT
9 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with GCC; see the file COPYING3. If not see
15 ;; <http://www.gnu.org/licenses/>.
17 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
20 ;; Define an insn type attribute. This is used in function unit delay
22 ;; multi0 is a multiple insn rtl whose first insn is in pipe0
23 ;; multi1 is a multiple insn rtl whose first insn is in pipe1
24 (define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
28 (define_attr "length" ""
31 (define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune")))
32 ;; Processor type -- this attribute must exactly match the processor_type
33 ;; enumeration in spu.h.
35 (define_attr "cpu" "spu"
36 (const (symbol_ref "spu_cpu_attr")))
38 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
39 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
41 (define_cpu_unit "pipe0,pipe1,fp,ls")
43 (define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
46 (define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
49 (define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
52 (define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
53 "pipe0 + fp, nothing*5")
55 (define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
56 "pipe0, fp, nothing*5")
58 ;; The behavior of the double precision is that both pipes stall
59 ;; for 6 cycles and the rest of the operation pipelines for
60 ;; 7 cycles. The simplest way to model this is to simply ignore
62 (define_insn_reservation "FPD" 7
63 (and (eq_attr "tune" "cell")
64 (eq_attr "type" "fpd"))
65 "pipe0 + pipe1, fp, nothing*5")
67 ;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined
68 (define_insn_reservation "FPD_CELLEDP" 9
69 (and (eq_attr "tune" "celledp")
70 (eq_attr "type" "fpd"))
71 "pipe0 + fp, nothing*8")
73 (define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
76 (define_insn_reservation "STORE" 1 (eq_attr "type" "store")
79 (define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
82 (define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
85 (define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
86 "pipe1 + ls, nothing*5")
88 (define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
91 (define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
92 "pipe0+pipe1, nothing*3")
94 (define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
97 (define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
100 ;; Force pipe0 to occur before pipe 1 in a cycle.
101 (absence_set "pipe0" "pipe1")
110 (UNSPEC_EXTEND_CMP 5)
153 (UNSPEC_SPU_REALIGN_LOAD 49)
154 (UNSPEC_SPU_MASK_FOR_LOAD 50)
158 (include "predicates.md")
159 (include "constraints.md")
164 (define_mode_iterator ALL [QI V16QI
172 ; Everything except DI and TI which are handled separately because
173 ; they need different constraints to correctly test VOIDmode constants
174 (define_mode_iterator MOV [QI V16QI
181 (define_mode_iterator DTI [DI TI])
183 (define_mode_iterator VINT [QI V16QI
189 (define_mode_iterator VQHSI [QI V16QI
193 (define_mode_iterator VHSI [HI V8HI
196 (define_mode_iterator VSDF [SF V4SF
199 (define_mode_iterator VSI [SI V4SI])
200 (define_mode_iterator VDI [DI V2DI])
201 (define_mode_iterator VSF [SF V4SF])
202 (define_mode_iterator VDF [DF V2DF])
204 (define_mode_iterator VCMP [V16QI
210 (define_mode_iterator VCMPU [V16QI
214 (define_mode_attr v [(V8HI "v") (V4SI "v")
217 (define_mode_attr bh [(QI "b") (V16QI "b")
221 (define_mode_attr d [(SF "") (V4SF "")
222 (DF "d") (V2DF "d")])
223 (define_mode_attr d6 [(SF "6") (V4SF "6")
224 (DF "d") (V2DF "d")])
226 (define_mode_attr f2i [(SF "si") (V4SF "v4si")
227 (DF "di") (V2DF "v2di")])
228 (define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
229 (DF "DI") (V2DF "V2DI")])
231 (define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
233 (define_mode_attr umask [(HI "f") (V8HI "f")
234 (SI "g") (V4SI "g")])
235 (define_mode_attr nmask [(HI "F") (V8HI "F")
236 (SI "G") (V4SI "G")])
238 ;; Used for carry and borrow instructions.
239 (define_mode_iterator CBOP [SI DI V4SI V2DI])
241 ;; Used in vec_set and vec_extract
242 (define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
243 (define_mode_attr inner [(V16QI "QI")
249 (define_mode_attr vmult [(V16QI "1")
255 (define_mode_attr voff [(V16QI "13")
265 (define_expand "mov<mode>"
266 [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
267 (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
270 if (spu_expand_mov(operands, <MODE>mode))
275 [(set (match_operand 0 "spu_reg_operand")
276 (match_operand 1 "immediate_operand"))]
280 (high (match_dup 1)))
282 (lo_sum (match_dup 0)
285 if (spu_split_immediate (operands))
291 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
292 (match_operand:SI 1 "immediate_operand" "s"))
297 ;; Whenever a function generates the 'pic' pattern above we need to
298 ;; load the pic_offset_table register.
299 ;; GCC doesn't deal well with labels in the middle of a block so we
300 ;; hardcode the offsets in the asm here.
301 (define_insn "load_pic_offset"
302 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
303 (unspec:SI [(const_int 0)] 0))
304 (set (match_operand:SI 1 "spu_reg_operand" "=r")
305 (unspec:SI [(const_int 0)] 0))]
307 "ila\t%1,.+8\;brsl\t%0,4"
308 [(set_attr "length" "8")
309 (set_attr "type" "multi0")])
314 (define_insn "_mov<mode>"
315 [(set (match_operand:MOV 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
316 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
317 "spu_valid_move (operands)"
325 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
327 (define_insn "low_<mode>"
328 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
329 (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
330 (match_operand:VSI 2 "immediate_operand" "i")))]
334 (define_insn "_movdi"
335 [(set (match_operand:DI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
336 (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
337 "spu_valid_move (operands)"
345 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
347 (define_insn "_movti"
348 [(set (match_operand:TI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
349 (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
350 "spu_valid_move (operands)"
358 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
360 (define_insn_and_split "load"
361 [(set (match_operand 0 "spu_reg_operand" "=r")
362 (match_operand 1 "memory_operand" "m"))
363 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
364 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))]
365 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
370 { spu_split_load(operands); DONE; })
372 (define_insn_and_split "store"
373 [(set (match_operand 0 "memory_operand" "=m")
374 (match_operand 1 "spu_reg_operand" "r"))
375 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
376 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
377 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
382 { spu_split_store(operands); DONE; })
384 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
386 (define_expand "cpat"
387 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
388 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
389 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
390 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
393 rtx x = gen_cpat_const (operands);
396 emit_move_insn (operands[0], x);
402 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
403 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
404 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
405 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
410 [(set_attr "type" "shuf")])
413 [(set (match_operand:TI 0 "spu_reg_operand")
414 (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
415 (match_operand:SI 2 "immediate_operand")
416 (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
418 [(set (match_dup:TI 0)
421 operands[4] = gen_cpat_const (operands);
428 (define_insn "extendqihi2"
429 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
430 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
434 (define_insn "extendhisi2"
435 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
436 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
440 (define_expand "extendsidi2"
441 [(set (match_dup:DI 2)
442 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
443 (set (match_operand:DI 0 "spu_reg_operand" "")
444 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
445 (parallel [(const_int 1)]))))]
448 operands[2] = gen_reg_rtx (DImode);
449 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
453 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
456 (match_operand:V2SI 1 "spu_reg_operand" "r")
457 (parallel [(const_int 1) ]))))]
461 (define_expand "extendqiti2"
462 [(set (match_operand:TI 0 "register_operand" "")
463 (sign_extend:TI (match_operand:QI 1 "register_operand" "")))]
465 "spu_expand_sign_extend(operands);
468 (define_expand "extendhiti2"
469 [(set (match_operand:TI 0 "register_operand" "")
470 (sign_extend:TI (match_operand:HI 1 "register_operand" "")))]
472 "spu_expand_sign_extend(operands);
475 (define_expand "extendsiti2"
476 [(set (match_operand:TI 0 "register_operand" "")
477 (sign_extend:TI (match_operand:SI 1 "register_operand" "")))]
479 "spu_expand_sign_extend(operands);
482 (define_expand "extendditi2"
483 [(set (match_operand:TI 0 "register_operand" "")
484 (sign_extend:TI (match_operand:DI 1 "register_operand" "")))]
486 "spu_expand_sign_extend(operands);
492 (define_insn "zero_extendqihi2"
493 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
494 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
496 "andi\t%0,%1,0x00ff")
498 (define_insn "zero_extendqisi2"
499 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
500 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
502 "andi\t%0,%1,0x00ff")
504 (define_expand "zero_extendhisi2"
505 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
506 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
507 (clobber (match_scratch:SI 2 "=&r"))]
510 rtx mask = gen_reg_rtx (SImode);
511 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
512 emit_move_insn (mask, GEN_INT (0xffff));
513 emit_insn (gen_andsi3(operands[0], op1, mask));
517 (define_insn "zero_extendsidi2"
518 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
519 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
522 [(set_attr "type" "shuf")])
524 (define_insn "zero_extendsiti2"
525 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
526 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
528 "rotqmbyi\t%0,%1,-12"
529 [(set_attr "type" "shuf")])
531 (define_insn "zero_extendditi2"
532 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
533 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
536 [(set_attr "type" "shuf")])
541 (define_insn "truncdiqi2"
542 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
543 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
546 [(set_attr "type" "shuf")])
548 (define_insn "truncdihi2"
549 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
550 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
553 [(set_attr "type" "shuf")])
555 (define_insn "truncdisi2"
556 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
557 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
560 [(set_attr "type" "shuf")])
562 (define_insn "trunctiqi2"
563 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
564 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
567 [(set_attr "type" "shuf")])
569 (define_insn "trunctihi2"
570 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
571 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
574 [(set_attr "type" "shuf")])
576 (define_insn "trunctisi2"
577 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
578 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
581 [(set_attr "type" "shuf")])
583 (define_insn "trunctidi2"
584 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
585 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
588 [(set_attr "type" "shuf")])
593 (define_insn "floatsisf2"
594 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
595 (float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
598 [(set_attr "type" "fp7")])
600 (define_insn "floatv4siv4sf2"
601 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
602 (float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
605 [(set_attr "type" "fp7")])
607 (define_insn "fix_truncsfsi2"
608 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
609 (fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
612 [(set_attr "type" "fp7")])
614 (define_insn "fix_truncv4sfv4si2"
615 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
616 (fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
619 [(set_attr "type" "fp7")])
621 (define_insn "floatunssisf2"
622 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
623 (unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
626 [(set_attr "type" "fp7")])
628 (define_insn "floatunsv4siv4sf2"
629 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
630 (unsigned_float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
633 [(set_attr "type" "fp7")])
635 (define_insn "fixuns_truncsfsi2"
636 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
637 (unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
640 [(set_attr "type" "fp7")])
642 (define_insn "fixuns_truncv4sfv4si2"
643 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
644 (unsigned_fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
647 [(set_attr "type" "fp7")])
649 (define_insn "extendsfdf2"
650 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
651 (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))]
654 [(set_attr "type" "fpd")])
656 (define_insn "truncdfsf2"
657 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
658 (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))]
661 [(set_attr "type" "fpd")])
663 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
664 (define_expand "floatsidf2"
665 [(set (match_operand:DF 0 "register_operand" "")
666 (float:DF (match_operand:SI 1 "register_operand" "")))]
669 rtx c0 = gen_reg_rtx (SImode);
670 rtx c1 = gen_reg_rtx (DFmode);
671 rtx r0 = gen_reg_rtx (SImode);
672 rtx r1 = gen_reg_rtx (DFmode);
674 emit_move_insn (c0, GEN_INT (-0x80000000ll));
675 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
676 emit_insn (gen_xorsi3 (r0, operands[1], c0));
677 emit_insn (gen_floatunssidf2 (r1, r0));
678 emit_insn (gen_subdf3 (operands[0], r1, c1));
682 (define_expand "floatunssidf2"
683 [(set (match_operand:DF 0 "register_operand" "=r")
684 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
688 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
689 0x06071415, 0x16178080);
690 rtx r0 = gen_reg_rtx (V16QImode);
696 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
698 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
699 insns = get_insns ();
701 emit_libcall_block (insns, operands[0], value,
702 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
706 emit_move_insn (r0, c0);
707 emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
712 (define_insn_and_split "floatunssidf2_internal"
713 [(set (match_operand:DF 0 "register_operand" "=r")
714 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))
715 (use (match_operand:V16QI 2 "register_operand" "r"))
716 (clobber (match_scratch:V4SI 3 "=&r"))
717 (clobber (match_scratch:V4SI 4 "=&r"))
718 (clobber (match_scratch:V4SI 5 "=&r"))
719 (clobber (match_scratch:V4SI 6 "=&r"))]
721 "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"
723 [(set (match_dup:DF 0)
724 (unsigned_float:DF (match_dup:SI 1)))]
727 rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
728 rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
729 rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
730 rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
731 emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
732 emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
733 emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
734 emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
735 emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
736 emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
737 emit_insn (gen_andc_v4si (ops[6],ops[6],ops[5]));
738 emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
739 emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
742 [(set_attr "length" "32")])
744 (define_expand "floatdidf2"
745 [(set (match_operand:DF 0 "register_operand" "")
746 (float:DF (match_operand:DI 1 "register_operand" "")))]
749 rtx c0 = gen_reg_rtx (DImode);
750 rtx r0 = gen_reg_rtx (DImode);
751 rtx r1 = gen_reg_rtx (DFmode);
752 rtx r2 = gen_reg_rtx (DImode);
753 rtx setneg = gen_reg_rtx (DImode);
754 rtx isneg = gen_reg_rtx (SImode);
755 rtx neg = gen_reg_rtx (DImode);
756 rtx mask = gen_reg_rtx (DImode);
758 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
760 emit_insn (gen_negdi2 (neg, operands[1]));
761 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
762 emit_insn (gen_extend_compare (mask, isneg));
763 emit_insn (gen_selb (r0, neg, operands[1], mask));
764 emit_insn (gen_andc_di (setneg, c0, mask));
766 emit_insn (gen_floatunsdidf2 (r1, r0));
768 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
769 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
773 (define_expand "floatunsdidf2"
774 [(set (match_operand:DF 0 "register_operand" "=r")
775 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
779 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
780 0x06071415, 0x16178080);
781 rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
782 rtx r0 = gen_reg_rtx (V16QImode);
783 rtx r1 = gen_reg_rtx (V4SImode);
789 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
791 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
792 insns = get_insns ();
794 emit_libcall_block (insns, operands[0], value,
795 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
799 emit_move_insn (r1, c1);
800 emit_move_insn (r0, c0);
801 emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
806 (define_insn_and_split "floatunsdidf2_internal"
807 [(set (match_operand:DF 0 "register_operand" "=r")
808 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))
809 (use (match_operand:V16QI 2 "register_operand" "r"))
810 (use (match_operand:V4SI 3 "register_operand" "r"))
811 (clobber (match_scratch:V4SI 4 "=&r"))
812 (clobber (match_scratch:V4SI 5 "=&r"))
813 (clobber (match_scratch:V4SI 6 "=&r"))]
815 "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"
817 [(set (match_operand:DF 0 "register_operand" "=r")
818 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
821 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
822 rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
823 rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
824 rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
825 rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
826 rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
827 emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
828 emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
829 emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
830 emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
831 emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
832 emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
833 emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
834 emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
835 emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
836 emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
839 [(set_attr "length" "40")])
844 (define_expand "addv16qi3"
845 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
846 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
847 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
850 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
851 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
852 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
853 rtx rhs_and = gen_reg_rtx (V8HImode);
854 rtx hi_char = gen_reg_rtx (V8HImode);
855 rtx lo_char = gen_reg_rtx (V8HImode);
856 rtx mask = gen_reg_rtx (V8HImode);
858 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
859 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
860 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
861 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
862 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
866 (define_insn "add<mode>3"
867 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
868 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
869 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
875 (define_expand "add<mode>3"
876 [(set (match_dup:VDI 3)
877 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
878 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
879 (set (match_dup:VDI 5)
880 (unspec:VDI [(match_dup 3)
882 (match_dup:TI 4)] UNSPEC_SHUFB))
883 (set (match_operand:VDI 0 "spu_reg_operand" "")
884 (unspec:VDI [(match_dup 1)
886 (match_dup 5)] UNSPEC_ADDX))]
889 unsigned char pat[16] = {
890 0x04, 0x05, 0x06, 0x07,
891 0x80, 0x80, 0x80, 0x80,
892 0x0c, 0x0d, 0x0e, 0x0f,
893 0x80, 0x80, 0x80, 0x80
895 operands[3] = gen_reg_rtx (<MODE>mode);
896 operands[4] = gen_reg_rtx (TImode);
897 operands[5] = gen_reg_rtx (<MODE>mode);
898 emit_move_insn (operands[4], array_to_constant (TImode, pat));
901 (define_insn "cg_<mode>"
902 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
903 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
904 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
908 (define_insn "cgx_<mode>"
909 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
910 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
911 (match_operand 2 "spu_reg_operand" "r")
912 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
916 (define_insn "addx_<mode>"
917 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
918 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
919 (match_operand 2 "spu_reg_operand" "r")
920 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
925 ;; This is not the most efficient implementation of addti3.
926 ;; We include this here because 1) the compiler needs it to be
927 ;; defined as the word size is 128-bit and 2) sometimes gcc
928 ;; substitutes an add for a constant left-shift. 2) is unlikely
929 ;; because we also give addti3 a high cost. In case gcc does
930 ;; generate TImode add, here is the code to do it.
931 ;; operand 2 is a nonmemory because the compiler requires it.
932 (define_insn "addti3"
933 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
934 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
935 (match_operand:TI 2 "spu_nonmem_operand" "r")))
936 (clobber (match_scratch:TI 3 "=&r"))]
945 [(set_attr "type" "multi0")
946 (set_attr "length" "28")])
948 (define_insn "add<mode>3"
949 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
950 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
951 (match_operand:VSF 2 "spu_reg_operand" "r")))]
954 [(set_attr "type" "fp6")])
956 (define_insn "add<mode>3"
957 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
958 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
959 (match_operand:VDF 2 "spu_reg_operand" "r")))]
962 [(set_attr "type" "fpd")])
967 (define_expand "subv16qi3"
968 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
969 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
970 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
973 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
974 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
975 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
976 rtx rhs_and = gen_reg_rtx (V8HImode);
977 rtx hi_char = gen_reg_rtx (V8HImode);
978 rtx lo_char = gen_reg_rtx (V8HImode);
979 rtx mask = gen_reg_rtx (V8HImode);
981 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
982 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
983 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
984 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
985 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
989 (define_insn "sub<mode>3"
990 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
991 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
992 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
998 (define_expand "sub<mode>3"
999 [(set (match_dup:VDI 3)
1000 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1001 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1002 (set (match_dup:VDI 5)
1003 (unspec:VDI [(match_dup 3)
1005 (match_dup:TI 4)] UNSPEC_SHUFB))
1006 (set (match_operand:VDI 0 "spu_reg_operand" "")
1007 (unspec:VDI [(match_dup 1)
1009 (match_dup 5)] UNSPEC_SFX))]
1012 unsigned char pat[16] = {
1013 0x04, 0x05, 0x06, 0x07,
1014 0xc0, 0xc0, 0xc0, 0xc0,
1015 0x0c, 0x0d, 0x0e, 0x0f,
1016 0xc0, 0xc0, 0xc0, 0xc0
1018 operands[3] = gen_reg_rtx (<MODE>mode);
1019 operands[4] = gen_reg_rtx (TImode);
1020 operands[5] = gen_reg_rtx (<MODE>mode);
1021 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1024 (define_insn "bg_<mode>"
1025 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1026 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1027 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1031 (define_insn "bgx_<mode>"
1032 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1033 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1034 (match_operand 2 "spu_reg_operand" "r")
1035 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1039 (define_insn "sfx_<mode>"
1040 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1041 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1042 (match_operand 2 "spu_reg_operand" "r")
1043 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1047 (define_insn "subti3"
1048 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1049 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1050 (match_operand:TI 2 "spu_reg_operand" "r")))
1051 (clobber (match_scratch:TI 3 "=&r"))
1052 (clobber (match_scratch:TI 4 "=&r"))
1053 (clobber (match_scratch:TI 5 "=&r"))
1054 (clobber (match_scratch:TI 6 "=&r"))]
1060 shlqbyi\t%5,%3,4\n\\
1064 shlqbyi\t%5,%3,4\n\\
1068 shlqbyi\t%5,%3,4\n\\
1070 [(set_attr "type" "multi0")
1071 (set_attr "length" "56")])
1073 (define_insn "sub<mode>3"
1074 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1075 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1076 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1079 [(set_attr "type" "fp6")])
1081 (define_insn "sub<mode>3"
1082 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1083 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1084 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1087 [(set_attr "type" "fpd")])
1092 (define_expand "negv16qi2"
1093 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1094 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1097 rtx zero = gen_reg_rtx (V16QImode);
1098 emit_move_insn (zero, CONST0_RTX (V16QImode));
1099 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1103 (define_insn "neg<mode>2"
1104 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1105 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1109 (define_expand "negdi2"
1110 [(set (match_operand:DI 0 "spu_reg_operand" "")
1111 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1114 rtx zero = gen_reg_rtx(DImode);
1115 emit_move_insn(zero, GEN_INT(0));
1116 emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1120 (define_expand "negti2"
1121 [(set (match_operand:TI 0 "spu_reg_operand" "")
1122 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1125 rtx zero = gen_reg_rtx(TImode);
1126 emit_move_insn(zero, GEN_INT(0));
1127 emit_insn (gen_subti3(operands[0], zero, operands[1]));
1131 (define_expand "neg<mode>2"
1133 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1134 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1135 (use (match_dup 2))])]
1137 "operands[2] = gen_reg_rtx (<F2I>mode);
1138 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1140 (define_expand "neg<mode>2"
1142 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1143 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1144 (use (match_dup 2))])]
1146 "operands[2] = gen_reg_rtx (<F2I>mode);
1147 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
1149 (define_insn_and_split "_neg<mode>2"
1150 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1151 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1152 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1156 [(set (match_dup:<F2I> 3)
1157 (xor:<F2I> (match_dup:<F2I> 4)
1158 (match_dup:<F2I> 2)))]
1160 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1161 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1167 (define_expand "abs<mode>2"
1169 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1170 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1171 (use (match_dup 2))])]
1173 "operands[2] = gen_reg_rtx (<F2I>mode);
1174 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1176 (define_expand "abs<mode>2"
1178 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1179 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1180 (use (match_dup 2))])]
1182 "operands[2] = gen_reg_rtx (<F2I>mode);
1183 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
1185 (define_insn_and_split "_abs<mode>2"
1186 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1187 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1188 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1192 [(set (match_dup:<F2I> 3)
1193 (and:<F2I> (match_dup:<F2I> 4)
1194 (match_dup:<F2I> 2)))]
1196 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1197 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1203 (define_insn "mulhi3"
1204 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1205 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1206 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1211 [(set_attr "type" "fp7")])
1213 (define_expand "mulv8hi3"
1214 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1215 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1216 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1219 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1220 rtx low = gen_reg_rtx (V4SImode);
1221 rtx high = gen_reg_rtx (V4SImode);
1222 rtx shift = gen_reg_rtx (V4SImode);
1223 rtx mask = gen_reg_rtx (V4SImode);
1225 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1226 emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1227 emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1228 emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1229 emit_insn (gen_selb (result, shift, low, mask));
1233 (define_expand "mul<mode>3"
1235 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1236 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1237 (match_operand:VSI 2 "spu_reg_operand" "")))
1238 (clobber (match_dup:VSI 3))
1239 (clobber (match_dup:VSI 4))
1240 (clobber (match_dup:VSI 5))
1241 (clobber (match_dup:VSI 6))])]
1244 operands[3] = gen_reg_rtx(<MODE>mode);
1245 operands[4] = gen_reg_rtx(<MODE>mode);
1246 operands[5] = gen_reg_rtx(<MODE>mode);
1247 operands[6] = gen_reg_rtx(<MODE>mode);
1250 (define_insn_and_split "_mulsi3"
1251 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1252 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1253 (match_operand:SI 2 "spu_arith_operand" "rK")))
1254 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1255 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1256 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1257 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1261 [(set (match_dup:SI 0)
1262 (mult:SI (match_dup:SI 1)
1265 HOST_WIDE_INT val = 0;
1266 rtx a = operands[3];
1267 rtx b = operands[4];
1268 rtx c = operands[5];
1269 rtx d = operands[6];
1270 if (GET_CODE(operands[2]) == CONST_INT)
1272 val = INTVAL(operands[2]);
1273 emit_move_insn(d, operands[2]);
1276 if (val && (val & 0xffff) == 0)
1278 emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1280 else if (val > 0 && val < 0x10000)
1282 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1283 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1284 emit_insn (gen_mpyu_si(c, operands[1], cst));
1285 emit_insn (gen_addsi3(operands[0], a, c));
1289 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1290 emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1291 emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1292 emit_insn (gen_addsi3(d, a, b));
1293 emit_insn (gen_addsi3(operands[0], d, c));
1298 (define_insn_and_split "_mulv4si3"
1299 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1300 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1301 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1302 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1303 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1304 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1305 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1309 [(set (match_dup:V4SI 0)
1310 (mult:V4SI (match_dup:V4SI 1)
1311 (match_dup:V4SI 2)))]
1313 rtx a = operands[3];
1314 rtx b = operands[4];
1315 rtx c = operands[5];
1316 rtx d = operands[6];
1317 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1318 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1319 emit_insn (gen_spu_mpyh(a, op1, op2));
1320 emit_insn (gen_spu_mpyh(b, op2, op1));
1321 emit_insn (gen_spu_mpyu(c, op1, op2));
1322 emit_insn (gen_addv4si3(d, a, b));
1323 emit_insn (gen_addv4si3(operands[0], d, c));
1327 (define_insn "mulhisi3"
1328 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1329 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1330 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1333 [(set_attr "type" "fp7")])
1335 (define_insn "mulhisi3_imm"
1336 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1337 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1338 (match_operand:SI 2 "imm_K_operand" "K")))]
1341 [(set_attr "type" "fp7")])
1343 (define_insn "umulhisi3"
1344 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1345 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1346 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1349 [(set_attr "type" "fp7")])
1351 (define_insn "umulhisi3_imm"
1352 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1353 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1354 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1357 [(set_attr "type" "fp7")])
1359 (define_insn "mpyu_si"
1360 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1361 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1363 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1364 (const_int 65535))))]
1369 [(set_attr "type" "fp7")])
1371 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1372 ;; It's faster to do the multiplies in parallel then add them. If we
1373 ;; merge a multiply and add it prevents the multiplies from happening in
1375 (define_insn "mpya_si"
1376 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1377 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1378 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1379 (match_operand:SI 3 "spu_reg_operand" "r")))]
1382 [(set_attr "type" "fp7")])
1384 (define_insn "mpyh_si"
1385 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1386 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1388 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1389 (const_int 65535))))]
1392 [(set_attr "type" "fp7")])
1394 (define_insn "mpys_si"
1395 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1397 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1398 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1402 [(set_attr "type" "fp7")])
1404 (define_insn "mpyhh_si"
1405 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1406 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1408 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1412 [(set_attr "type" "fp7")])
1414 (define_insn "mpyhhu_si"
1415 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1416 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1418 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1422 [(set_attr "type" "fp7")])
1424 (define_insn "mpyhha_si"
1425 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1426 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1428 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1430 (match_operand:SI 3 "spu_reg_operand" "0")))]
1433 [(set_attr "type" "fp7")])
1435 (define_insn "mul<mode>3"
1436 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1437 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1438 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1441 [(set_attr "type" "fp<d6>")])
1443 (define_insn "fma_<mode>"
1444 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1445 (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1446 (match_operand:VSF 2 "spu_reg_operand" "r"))
1447 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1450 [(set_attr "type" "fp6")])
1452 (define_insn "fnms_<mode>"
1453 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1454 (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1455 (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1456 (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1459 [(set_attr "type" "fp6")])
1461 (define_insn "fms_<mode>"
1462 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1463 (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1464 (match_operand:VSF 2 "spu_reg_operand" "r"))
1465 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1468 [(set_attr "type" "fp6")])
1470 (define_insn "fma_<mode>"
1471 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1472 (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1473 (match_operand:VDF 2 "spu_reg_operand" "r"))
1474 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1477 [(set_attr "type" "fpd")])
1479 (define_insn "fnma_<mode>"
1480 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1481 (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1482 (match_operand:VDF 2 "spu_reg_operand" "r"))
1483 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1486 [(set_attr "type" "fpd")])
1488 (define_insn "fnms_<mode>"
1489 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1490 (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1491 (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1492 (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1495 [(set_attr "type" "fpd")])
1497 (define_insn "fms_<mode>"
1498 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1499 (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1500 (match_operand:VDF 2 "spu_reg_operand" "r"))
1501 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1504 [(set_attr "type" "fpd")])
1507 ;; mul highpart, used for divide by constant optimizations.
1509 (define_expand "smulsi3_highpart"
1510 [(set (match_operand:SI 0 "register_operand" "")
1513 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1514 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1518 rtx t0 = gen_reg_rtx (SImode);
1519 rtx t1 = gen_reg_rtx (SImode);
1520 rtx t2 = gen_reg_rtx (SImode);
1521 rtx t3 = gen_reg_rtx (SImode);
1522 rtx t4 = gen_reg_rtx (SImode);
1523 rtx t5 = gen_reg_rtx (SImode);
1524 rtx t6 = gen_reg_rtx (SImode);
1525 rtx t7 = gen_reg_rtx (SImode);
1526 rtx t8 = gen_reg_rtx (SImode);
1527 rtx t9 = gen_reg_rtx (SImode);
1528 rtx t11 = gen_reg_rtx (SImode);
1529 rtx t12 = gen_reg_rtx (SImode);
1530 rtx t14 = gen_reg_rtx (SImode);
1531 rtx t15 = gen_reg_rtx (HImode);
1532 rtx t16 = gen_reg_rtx (HImode);
1533 rtx t17 = gen_reg_rtx (HImode);
1534 rtx t18 = gen_reg_rtx (HImode);
1535 rtx t19 = gen_reg_rtx (SImode);
1536 rtx t20 = gen_reg_rtx (SImode);
1537 rtx t21 = gen_reg_rtx (SImode);
1538 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1539 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1540 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1541 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1543 rtx insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1544 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1545 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1546 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1547 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1548 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1549 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1550 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1552 /* Gen carry bits (in t9 and t11). */
1553 emit_insn (gen_addsi3 (t8, t2, t3));
1554 emit_insn (gen_cg_si (t9, t2, t3));
1555 emit_insn (gen_cg_si (t11, t8, t4));
1557 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1558 emit_insn (gen_addx_si (t12, t5, t6, t9));
1559 emit_insn (gen_addx_si (t14, t12, t7, t11));
1561 /* mpys treats both operands as signed when we really want it to treat
1562 the first operand as signed and the second operand as unsigned.
1563 The code below corrects for that difference. */
1564 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1565 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1566 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1567 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1568 emit_insn (gen_extendhisi2 (t19, t17));
1569 emit_insn (gen_extendhisi2 (t20, t18));
1570 emit_insn (gen_addsi3 (t21, t19, t20));
1571 emit_insn (gen_addsi3 (operands[0], t14, t21));
1572 unshare_all_rtl_in_chain (insn);
1576 (define_expand "umulsi3_highpart"
1577 [(set (match_operand:SI 0 "register_operand" "")
1580 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1581 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1586 rtx t0 = gen_reg_rtx (SImode);
1587 rtx t1 = gen_reg_rtx (SImode);
1588 rtx t2 = gen_reg_rtx (SImode);
1589 rtx t3 = gen_reg_rtx (SImode);
1590 rtx t4 = gen_reg_rtx (SImode);
1591 rtx t5 = gen_reg_rtx (SImode);
1592 rtx t6 = gen_reg_rtx (SImode);
1593 rtx t7 = gen_reg_rtx (SImode);
1594 rtx t8 = gen_reg_rtx (SImode);
1595 rtx t9 = gen_reg_rtx (SImode);
1596 rtx t10 = gen_reg_rtx (SImode);
1597 rtx t12 = gen_reg_rtx (SImode);
1598 rtx t13 = gen_reg_rtx (SImode);
1599 rtx t14 = gen_reg_rtx (SImode);
1600 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1601 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1602 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1604 rtx insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1605 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1606 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1607 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1608 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1609 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1610 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1611 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1612 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1614 /* Gen carry bits (in t10 and t12). */
1615 emit_insn (gen_addsi3 (t9, t1, t5));
1616 emit_insn (gen_cg_si (t10, t1, t5));
1617 emit_insn (gen_cg_si (t12, t9, t6));
1619 /* Gen high 32 bits in operand[0]. */
1620 emit_insn (gen_addx_si (t13, t4, t7, t10));
1621 emit_insn (gen_addx_si (t14, t13, t8, t12));
1622 emit_insn (gen_movsi (operands[0], t14));
1623 unshare_all_rtl_in_chain (insn);
1630 ;; Not necessarily the best implementation of divide but faster then
1631 ;; the default that gcc provides because this is inlined and it uses
1633 (define_insn "divmodsi4"
1634 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1635 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1636 (match_operand:SI 2 "spu_reg_operand" "r")))
1637 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1638 (mod:SI (match_dup 1)
1640 (clobber (match_scratch:SI 4 "=&r"))
1641 (clobber (match_scratch:SI 5 "=&r"))
1642 (clobber (match_scratch:SI 6 "=&r"))
1643 (clobber (match_scratch:SI 7 "=&r"))
1644 (clobber (match_scratch:SI 8 "=&r"))
1645 (clobber (match_scratch:SI 9 "=&r"))
1646 (clobber (match_scratch:SI 10 "=&r"))
1647 (clobber (match_scratch:SI 11 "=&r"))
1648 (clobber (match_scratch:SI 12 "=&r"))
1649 (clobber (reg:SI 130))]
1657 selb %8,%8,%1,%10\\n\\
1658 selb %9,%9,%2,%11\\n\\
1664 shlqbyi %3,%8,0\\n\\
1665 xor %11,%10,%11\\n\\
1669 1: or %12,%0,%5\\n\\
1670 rotqmbii %5,%5,-1\\n\\
1674 rotqmbii %4,%4,-1\\n\\
1675 selb %0,%12,%0,%6\\n\\
1677 selb %3,%7,%3,%6\\n\\
1681 selb %3,%8,%3,%10\\n\\
1683 [(set_attr "type" "multi0")
1684 (set_attr "length" "128")])
1686 (define_insn "udivmodsi4"
1687 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1688 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1689 (match_operand:SI 2 "spu_reg_operand" "r")))
1690 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1691 (umod:SI (match_dup 1)
1693 (clobber (match_scratch:SI 4 "=&r"))
1694 (clobber (match_scratch:SI 5 "=&r"))
1695 (clobber (match_scratch:SI 6 "=&r"))
1696 (clobber (match_scratch:SI 7 "=&r"))
1697 (clobber (match_scratch:SI 8 "=&r"))
1698 (clobber (reg:SI 130))]
1711 rotqmbii %5,%5,-1\\n\\
1715 rotqmbii %4,%4,-1\\n\\
1716 selb %0,%8,%0,%6\\n\\
1718 selb %3,%7,%3,%6\\n\\
1721 [(set_attr "type" "multi0")
1722 (set_attr "length" "80")])
1724 (define_insn_and_split "div<mode>3"
1725 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1726 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1727 (match_operand:VSF 2 "spu_reg_operand" "r")))
1728 (clobber (match_scratch:VSF 3 "=&r"))
1729 (clobber (match_scratch:VSF 4 "=&r"))]
1733 [(set (match_dup:VSF 0)
1734 (div:VSF (match_dup:VSF 1)
1736 (clobber (match_dup:VSF 3))
1737 (clobber (match_dup:VSF 4))]
1739 emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1740 emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1741 emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1742 emit_insn (gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
1743 emit_insn (gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
1747 ;; Taken from STI's gcc
1748 ;; Does not correctly handle INF or NAN.
1749 (define_expand "divdf3"
1750 [(set (match_operand:DF 0 "register_operand" "=r")
1751 (div:DF (match_operand:DF 1 "register_operand" "r")
1752 (match_operand:DF 2 "register_operand" "r")))]
1753 "flag_finite_math_only"
1757 divdf3 (double x, double y)
1760 float y_f = (float) y;
1763 x0 = spu_extract(spu_re(spu_promote(y_f, 0)), 0);
1764 x1 = (double)(x0 * (2.0f - y_f * x0));
1765 x2 = x1 * (2.0 - y * x1);
1766 return (x * x2 * (2.0 - y * x2));
1770 rtx dst = operands[0];
1771 rtx x = operands[1];
1772 rtx y = operands[2];
1773 rtx y_f = gen_reg_rtx(SFmode);
1774 rtx x0_f = gen_reg_rtx(SFmode);
1775 rtx x1_f = gen_reg_rtx(SFmode);
1776 rtx x1 = gen_reg_rtx(DFmode);
1777 rtx x2 = gen_reg_rtx(DFmode);
1778 rtx t1_f = gen_reg_rtx(SFmode);
1779 rtx t1 = gen_reg_rtx(DFmode);
1780 rtx two = gen_reg_rtx(DFmode);
1781 rtx two_f = gen_reg_rtx(SFmode);
1783 emit_insn (gen_truncdfsf2 (y_f, y));
1784 emit_insn (gen_frest_sf (x0_f, y_f));
1785 emit_insn (gen_fi_sf (x0_f, y_f, x0_f));
1786 emit_insn (gen_movsf (two_f, spu_float_const(\"2.0\",SFmode)));
1787 emit_insn (gen_fnms_sf (t1_f, y_f, x0_f, two_f));
1788 emit_insn (gen_mulsf3 (x1_f, t1_f, x0_f));
1789 emit_insn (gen_extendsfdf2 (x1, x1_f));
1790 emit_insn (gen_extendsfdf2 (two, two_f));
1791 emit_insn (gen_movdf (t1, two));
1792 emit_insn (gen_fnms_df (t1, y, x1, t1));
1793 emit_insn (gen_muldf3 (x2, x1, t1));
1794 emit_insn (gen_fnms_df (two, y, x2, two));
1795 emit_insn (gen_muldf3 (dst, x2, two));
1796 emit_insn (gen_muldf3 (dst, dst, x));
1802 (define_insn_and_split "sqrtsf2"
1803 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1804 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1805 (clobber (match_scratch:SF 2 "=&r"))
1806 (clobber (match_scratch:SF 3 "=&r"))
1807 (clobber (match_scratch:SF 4 "=&r"))
1808 (clobber (match_scratch:SF 5 "=&r"))]
1812 [(set (match_dup:SF 0)
1813 (sqrt:SF (match_dup:SF 1)))
1814 (clobber (match_dup:SF 2))
1815 (clobber (match_dup:SF 3))
1816 (clobber (match_dup:SF 4))
1817 (clobber (match_dup:SF 5))]
1819 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1820 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1821 emit_insn (gen_frsqest_sf(operands[2],operands[1]));
1822 emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
1823 emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
1824 emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
1825 emit_insn (gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1826 emit_insn (gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1830 (define_insn "frest_<mode>"
1831 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1832 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1835 [(set_attr "type" "shuf")])
1837 (define_insn "frsqest_<mode>"
1838 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1839 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1842 [(set_attr "type" "shuf")])
1844 (define_insn "fi_<mode>"
1845 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1846 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1847 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1850 [(set_attr "type" "fp7")])
1855 (define_insn "and<mode>3"
1856 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1857 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1858 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1862 and%j2i\t%0,%1,%J2")
1864 (define_insn "anddi3"
1865 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1866 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1867 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1871 and%k2i\t%0,%1,%K2")
1873 (define_insn "andti3"
1874 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1875 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1876 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1880 and%m2i\t%0,%1,%L2")
1882 (define_insn "andc_<mode>"
1883 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1884 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1885 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1889 (define_insn "nand_<mode>"
1890 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1891 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1892 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1899 (define_insn "ior<mode>3"
1900 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1901 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
1902 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
1909 (define_insn "iordi3"
1910 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
1911 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
1912 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
1919 (define_insn "iorti3"
1920 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
1921 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
1922 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
1929 (define_insn "orc_<mode>"
1930 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1931 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1932 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1936 (define_insn "nor_<mode>"
1937 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1938 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1939 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1945 (define_insn "xor<mode>3"
1946 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1947 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1948 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
1952 xor%j2i\t%0,%1,%J2")
1954 (define_insn "xordi3"
1955 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1956 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1957 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1961 xor%k2i\t%0,%1,%K2")
1963 (define_insn "xorti3"
1964 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1965 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1966 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1970 xor%m2i\t%0,%1,%L2")
1972 (define_insn "eqv_<mode>"
1973 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1974 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1975 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1981 (define_insn "one_cmpl<mode>2"
1982 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1983 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
1990 (define_expand "selb"
1991 [(set (match_operand 0 "spu_reg_operand" "")
1992 (unspec [(match_operand 1 "spu_reg_operand" "")
1993 (match_operand 2 "spu_reg_operand" "")
1994 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
1997 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
1998 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2003 ;; This could be defined as a combination of logical operations, but at
2004 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2005 (define_insn "_selb"
2006 [(set (match_operand 0 "spu_reg_operand" "=r")
2007 (unspec [(match_operand 1 "spu_reg_operand" "r")
2008 (match_operand 2 "spu_reg_operand" "r")
2009 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2010 "GET_MODE(operands[0]) == GET_MODE(operands[1])
2011 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2012 "selb\t%0,%1,%2,%3")
2015 ;; Misc. byte/bit operations
2016 ;; clz/ctz/ffs/popcount/parity
2019 (define_insn "clz<mode>2"
2020 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2021 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2025 (define_expand "ctz<mode>2"
2027 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2028 (set (match_dup 3) (and:VSI (match_dup 1)
2030 (set (match_dup 4) (clz:VSI (match_dup 3)))
2031 (set (match_operand:VSI 0 "spu_reg_operand" "")
2032 (minus:VSI (match_dup 5) (match_dup 4)))]
2035 operands[2] = gen_reg_rtx (<MODE>mode);
2036 operands[3] = gen_reg_rtx (<MODE>mode);
2037 operands[4] = gen_reg_rtx (<MODE>mode);
2038 operands[5] = spu_const(<MODE>mode, 31);
2041 (define_expand "ffs<mode>2"
2043 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2044 (set (match_dup 3) (and:VSI (match_dup 1)
2046 (set (match_dup 4) (clz:VSI (match_dup 3)))
2047 (set (match_operand:VSI 0 "spu_reg_operand" "")
2048 (minus:VSI (match_dup 5) (match_dup 4)))]
2051 operands[2] = gen_reg_rtx (<MODE>mode);
2052 operands[3] = gen_reg_rtx (<MODE>mode);
2053 operands[4] = gen_reg_rtx (<MODE>mode);
2054 operands[5] = spu_const(<MODE>mode, 32);
2057 (define_expand "popcountsi2"
2059 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2062 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2063 (set (match_operand:SI 0 "spu_reg_operand" "")
2064 (sign_extend:SI (match_dup 3)))]
2067 operands[2] = gen_reg_rtx (SImode);
2068 operands[3] = gen_reg_rtx (HImode);
2071 (define_expand "paritysi2"
2072 [(set (match_operand:SI 0 "spu_reg_operand" "")
2073 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2076 operands[2] = gen_reg_rtx (SImode);
2077 emit_insn (gen_popcountsi2(operands[2], operands[1]));
2078 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2082 (define_insn "cntb_si"
2083 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2084 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2088 [(set_attr "type" "fxb")])
2090 (define_insn "cntb_v16qi"
2091 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2092 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2096 [(set_attr "type" "fxb")])
2098 (define_insn "sumb_si"
2099 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2100 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2103 [(set_attr "type" "fxb")])
2108 (define_insn "<v>ashl<mode>3"
2109 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2110 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2111 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2115 shl<bh>i\t%0,%1,%<umask>2"
2116 [(set_attr "type" "fx3")])
2118 (define_insn_and_split "ashldi3"
2119 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2120 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2121 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2122 (clobber (match_scratch:SI 3 "=&r,X"))]
2126 [(set (match_dup:DI 0)
2127 (ashift:DI (match_dup:DI 1)
2130 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2131 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2132 rtx op2 = operands[2];
2133 rtx op3 = operands[3];
2135 if (GET_CODE (operands[2]) == REG)
2137 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2138 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2139 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2140 emit_insn (gen_shlqbi_ti (op0, op0, op3));
2144 HOST_WIDE_INT val = INTVAL (operands[2]);
2145 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2146 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2148 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2153 (define_expand "ashlti3"
2154 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2155 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2156 (match_operand:SI 2 "spu_nonmem_operand" "")))
2157 (clobber (match_dup:TI 3))])]
2159 "if (GET_CODE (operands[2]) == CONST_INT)
2161 emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2164 operands[3] = gen_reg_rtx (TImode);")
2166 (define_insn_and_split "ashlti3_imm"
2167 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2168 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2169 (match_operand:SI 2 "immediate_operand" "O,P")))]
2174 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2175 [(set (match_dup:TI 0)
2176 (ashift:TI (match_dup:TI 1)
2178 (set (match_dup:TI 0)
2179 (ashift:TI (match_dup:TI 0)
2182 HOST_WIDE_INT val = INTVAL(operands[2]);
2183 operands[3] = GEN_INT (val&7);
2184 operands[4] = GEN_INT (val&-8);
2186 [(set_attr "type" "shuf,shuf")])
2188 (define_insn_and_split "ashlti3_reg"
2189 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2190 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2191 (match_operand:SI 2 "spu_reg_operand" "r")))
2192 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2196 [(set (match_dup:TI 3)
2197 (ashift:TI (match_dup:TI 1)
2198 (and:SI (match_dup:SI 2)
2200 (set (match_dup:TI 0)
2201 (ashift:TI (match_dup:TI 3)
2202 (and:SI (match_dup:SI 2)
2206 (define_insn "shlqbybi_ti"
2207 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2208 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2209 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2215 [(set_attr "type" "shuf,shuf")])
2217 (define_insn "shlqbi_ti"
2218 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2219 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2220 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2226 [(set_attr "type" "shuf,shuf")])
2228 (define_insn "shlqby_ti"
2229 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2230 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2231 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2237 [(set_attr "type" "shuf,shuf")])
2242 (define_insn_and_split "<v>lshr<mode>3"
2243 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2244 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2245 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2246 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2250 rot<bh>mi\t%0,%1,-%<umask>2"
2251 "reload_completed && GET_CODE (operands[2]) == REG"
2252 [(set (match_dup:VHSI 3)
2253 (neg:VHSI (match_dup:VHSI 2)))
2254 (set (match_dup:VHSI 0)
2255 (lshiftrt:VHSI (match_dup:VHSI 1)
2256 (neg:VHSI (match_dup:VHSI 3))))]
2258 [(set_attr "type" "*,fx3")])
2261 (define_insn "rotm_<mode>"
2262 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2263 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2264 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2268 rot<bh>mi\t%0,%1,-%<nmask>2"
2269 [(set_attr "type" "fx3")])
2271 (define_expand "lshr<mode>3"
2272 [(parallel [(set (match_operand:DTI 0 "spu_reg_operand" "")
2273 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "")
2274 (match_operand:SI 2 "spu_nonmem_operand" "")))
2275 (clobber (match_dup:DTI 3))
2276 (clobber (match_dup:SI 4))
2277 (clobber (match_dup:SI 5))])]
2279 "if (GET_CODE (operands[2]) == CONST_INT)
2281 emit_insn (gen_lshr<mode>3_imm(operands[0], operands[1], operands[2]));
2284 operands[3] = gen_reg_rtx (<MODE>mode);
2285 operands[4] = gen_reg_rtx (SImode);
2286 operands[5] = gen_reg_rtx (SImode);")
2288 (define_insn_and_split "lshr<mode>3_imm"
2289 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2290 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2291 (match_operand:SI 2 "immediate_operand" "O,P")))]
2294 rotqmbyi\t%0,%1,-%h2
2295 rotqmbii\t%0,%1,-%e2"
2296 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2297 [(set (match_dup:DTI 0)
2298 (lshiftrt:DTI (match_dup:DTI 1)
2300 (set (match_dup:DTI 0)
2301 (lshiftrt:DTI (match_dup:DTI 0)
2304 HOST_WIDE_INT val = INTVAL(operands[2]);
2305 operands[4] = GEN_INT (val&7);
2306 operands[5] = GEN_INT (val&-8);
2308 [(set_attr "type" "shuf,shuf")])
2310 (define_insn_and_split "lshr<mode>3_reg"
2311 [(set (match_operand:DTI 0 "spu_reg_operand" "=r")
2312 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r")
2313 (match_operand:SI 2 "spu_reg_operand" "r")))
2314 (clobber (match_operand:DTI 3 "spu_reg_operand" "=&r"))
2315 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
2316 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))]
2320 [(set (match_dup:DTI 3)
2321 (lshiftrt:DTI (match_dup:DTI 1)
2322 (and:SI (neg:SI (match_dup:SI 4))
2324 (set (match_dup:DTI 0)
2325 (lshiftrt:DTI (match_dup:DTI 3)
2326 (and:SI (neg:SI (and:SI (match_dup:SI 5)
2330 emit_insn (gen_subsi3(operands[4], GEN_INT(0), operands[2]));
2331 emit_insn (gen_subsi3(operands[5], GEN_INT(7), operands[2]));
2334 (define_insn "rotqmbybi_<mode>"
2335 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2336 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2337 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2343 rotqmbyi\t%0,%1,-%H2"
2344 [(set_attr "type" "shuf")])
2346 (define_insn "rotqmbi_<mode>"
2347 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2348 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2349 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2354 rotqmbii\t%0,%1,-%E2"
2355 [(set_attr "type" "shuf")])
2357 (define_insn "rotqmby_<mode>"
2358 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2359 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2360 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2365 rotqmbyi\t%0,%1,-%F2"
2366 [(set_attr "type" "shuf")])
2371 (define_insn_and_split "<v>ashr<mode>3"
2372 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2373 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2374 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2375 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2379 rotma<bh>i\t%0,%1,-%<umask>2"
2380 "reload_completed && GET_CODE (operands[2]) == REG"
2381 [(set (match_dup:VHSI 3)
2382 (neg:VHSI (match_dup:VHSI 2)))
2383 (set (match_dup:VHSI 0)
2384 (ashiftrt:VHSI (match_dup:VHSI 1)
2385 (neg:VHSI (match_dup:VHSI 3))))]
2387 [(set_attr "type" "*,fx3")])
2390 (define_insn "rotma_<mode>"
2391 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2392 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2393 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2397 rotma<bh>i\t%0,%1,-%<nmask>2"
2398 [(set_attr "type" "fx3")])
2400 (define_insn_and_split "ashrdi3"
2401 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2402 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2403 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2404 (clobber (match_scratch:TI 3 "=&r,&r"))
2405 (clobber (match_scratch:TI 4 "=&r,&r"))
2406 (clobber (match_scratch:SI 5 "=&r,&r"))]
2410 [(set (match_dup:DI 0)
2411 (ashiftrt:DI (match_dup:DI 1)
2414 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2415 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2416 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2417 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2418 rtx op2 = operands[2];
2419 rtx op3 = operands[3];
2420 rtx op4 = operands[4];
2421 rtx op5 = operands[5];
2423 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2425 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2426 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2427 emit_insn (gen_spu_fsm (op0v, op0s));
2429 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2431 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2432 HOST_WIDE_INT val = INTVAL (op2);
2433 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2434 emit_insn (gen_spu_xswd (op0d, op0v));
2436 emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2440 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2441 unsigned char arr[16] = {
2442 0xff, 0xff, 0xff, 0xff,
2443 0xff, 0xff, 0xff, 0xff,
2444 0x00, 0x00, 0x00, 0x00,
2445 0x00, 0x00, 0x00, 0x00
2448 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2449 emit_move_insn (op4, array_to_constant (TImode, arr));
2450 emit_insn (gen_spu_fsm (op3v, op5));
2452 if (GET_CODE (operands[2]) == REG)
2454 emit_insn (gen_selb (op4, op3, op1, op4));
2455 emit_insn (gen_negsi2 (op5, op2));
2456 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2457 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2461 HOST_WIDE_INT val = -INTVAL (op2);
2462 emit_insn (gen_selb (op0, op3, op1, op4));
2464 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2466 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2473 (define_expand "ashrti3"
2474 [(set (match_operand:TI 0 "spu_reg_operand" "")
2475 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "")
2476 (match_operand:SI 2 "spu_nonmem_operand" "")))]
2479 rtx sign_shift = gen_reg_rtx (SImode);
2480 rtx sign_mask = gen_reg_rtx (TImode);
2481 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2482 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2483 rtx t = gen_reg_rtx (TImode);
2484 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2485 emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2486 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2487 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2488 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2489 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2493 ;; fsm is used after rotam to replicate the sign across the whole register.
2494 (define_insn "fsm_ti"
2495 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2496 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2499 [(set_attr "type" "shuf")])
2504 (define_insn "<v>rotl<mode>3"
2505 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2506 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2507 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2511 rot<bh>i\t%0,%1,%<umask>2"
2512 [(set_attr "type" "fx3")])
2514 (define_insn "rotlti3"
2515 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2516 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2517 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2520 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2523 rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2524 [(set_attr "length" "8,4,4,8")
2525 (set_attr "type" "multi1,shuf,shuf,multi1")])
2527 (define_insn "rotqbybi_ti"
2528 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2529 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2530 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2536 [(set_attr "type" "shuf,shuf")])
2538 (define_insn "rotqby_ti"
2539 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2540 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2541 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2547 [(set_attr "type" "shuf,shuf")])
2549 (define_insn "rotqbi_ti"
2550 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2551 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2552 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2558 [(set_attr "type" "shuf,shuf")])
2561 ;; struct extract/insert
2562 ;; We have to handle mem's because GCC will generate invalid SUBREG's
2563 ;; if it handles them. We generate better code anyway.
2565 (define_expand "extv"
2566 [(set (match_operand 0 "register_operand" "")
2567 (sign_extract (match_operand 1 "register_operand" "")
2568 (match_operand:SI 2 "const_int_operand" "")
2569 (match_operand:SI 3 "const_int_operand" "")))]
2571 { spu_expand_extv(operands, 0); DONE; })
2573 (define_expand "extzv"
2574 [(set (match_operand 0 "register_operand" "")
2575 (zero_extract (match_operand 1 "register_operand" "")
2576 (match_operand:SI 2 "const_int_operand" "")
2577 (match_operand:SI 3 "const_int_operand" "")))]
2579 { spu_expand_extv(operands, 1); DONE; })
2581 (define_expand "insv"
2582 [(set (zero_extract (match_operand 0 "register_operand" "")
2583 (match_operand:SI 1 "const_int_operand" "")
2584 (match_operand:SI 2 "const_int_operand" ""))
2585 (match_operand 3 "nonmemory_operand" ""))]
2587 { spu_expand_insv(operands); DONE; })
2590 ;; String/block move insn.
2591 ;; Argument 0 is the destination
2592 ;; Argument 1 is the source
2593 ;; Argument 2 is the length
2594 ;; Argument 3 is the alignment
2596 (define_expand "movstrsi"
2597 [(parallel [(set (match_operand:BLK 0 "" "")
2598 (match_operand:BLK 1 "" ""))
2599 (use (match_operand:SI 2 "" ""))
2600 (use (match_operand:SI 3 "" ""))])]
2604 if (spu_expand_block_move (operands))
2613 (define_insn "indirect_jump"
2614 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2617 [(set_attr "type" "br")])
2621 (label_ref (match_operand 0 "" "")))]
2624 [(set_attr "type" "br")])
2629 ;; This will be used for leaf functions, that don't save any regs and
2630 ;; don't have locals on stack, maybe... that is for functions that
2631 ;; don't change $sp and don't need to save $lr.
2632 (define_expand "return"
2637 ;; used in spu_expand_epilogue to generate return from a function and
2638 ;; explicitly set use of $lr.
2640 (define_insn "_return"
2644 [(set_attr "type" "br")])
2650 (define_insn "ceq_<mode>"
2651 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2652 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2653 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2657 ceq<bh>i\t%0,%1,%2")
2659 (define_insn_and_split "ceq_di"
2660 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2661 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2662 (match_operand:DI 2 "spu_reg_operand" "r")))]
2666 [(set (match_dup:SI 0)
2667 (eq:SI (match_dup:DI 1)
2670 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2671 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2672 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2673 emit_insn (gen_ceq_v4si (op0, op1, op2));
2674 emit_insn (gen_spu_gb (op0, op0));
2675 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2680 ;; We provide the TI compares for completeness and because some parts of
2681 ;; gcc/libgcc use them, even though user code might never see it.
2682 (define_insn "ceq_ti"
2683 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2684 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2685 (match_operand:TI 2 "spu_reg_operand" "r")))]
2687 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2688 [(set_attr "type" "multi0")
2689 (set_attr "length" "12")])
2691 (define_insn "ceq_<mode>"
2692 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2693 (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
2694 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2698 (define_insn "cmeq_<mode>"
2699 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2700 (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2701 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2705 ;; These implementations will ignore checking of NaN or INF if
2706 ;; compiled with option -ffinite-math-only.
2707 (define_expand "ceq_df"
2708 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2709 (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
2710 (match_operand:DF 2 "const_zero_operand" "i")))]
2713 if (spu_arch == PROCESSOR_CELL)
2715 rtx ra = gen_reg_rtx (V4SImode);
2716 rtx rb = gen_reg_rtx (V4SImode);
2717 rtx temp = gen_reg_rtx (TImode);
2718 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2719 rtx temp2 = gen_reg_rtx (V4SImode);
2720 rtx biteq = gen_reg_rtx (V4SImode);
2721 rtx ahi_inf = gen_reg_rtx (V4SImode);
2722 rtx a_nan = gen_reg_rtx (V4SImode);
2723 rtx a_abs = gen_reg_rtx (V4SImode);
2724 rtx b_abs = gen_reg_rtx (V4SImode);
2725 rtx iszero = gen_reg_rtx (V4SImode);
2726 rtx sign_mask = gen_reg_rtx (V4SImode);
2727 rtx nan_mask = gen_reg_rtx (V4SImode);
2728 rtx hihi_promote = gen_reg_rtx (TImode);
2729 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
2730 0x7FFFFFFF, 0xFFFFFFFF);
2732 emit_move_insn (sign_mask, pat);
2733 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
2735 emit_move_insn (nan_mask, pat);
2736 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
2737 0x08090A0B, 0x18191A1B);
2738 emit_move_insn (hihi_promote, pat);
2740 emit_insn (gen_spu_convert (ra, operands[1]));
2741 emit_insn (gen_spu_convert (rb, operands[2]));
2742 emit_insn (gen_ceq_v4si (biteq, ra, rb));
2743 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
2745 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
2747 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
2748 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
2749 if (!flag_finite_math_only)
2751 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
2752 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
2753 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
2755 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
2756 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
2758 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
2759 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
2760 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
2762 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
2763 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
2764 if (!flag_finite_math_only)
2766 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
2768 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
2773 (define_insn "ceq_<mode>_celledp"
2774 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
2775 (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
2776 (match_operand:VDF 2 "spu_reg_operand" "r")))]
2777 "spu_arch == PROCESSOR_CELLEDP"
2779 [(set_attr "type" "fpd")])
2781 (define_insn "cmeq_<mode>_celledp"
2782 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
2783 (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
2784 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
2785 "spu_arch == PROCESSOR_CELLEDP"
2787 [(set_attr "type" "fpd")])
2789 (define_expand "ceq_v2df"
2790 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
2791 (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
2792 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
2795 if (spu_arch == PROCESSOR_CELL)
2797 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
2798 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
2799 rtx temp = gen_reg_rtx (TImode);
2800 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2801 rtx temp2 = gen_reg_rtx (V4SImode);
2802 rtx biteq = gen_reg_rtx (V4SImode);
2803 rtx ahi_inf = gen_reg_rtx (V4SImode);
2804 rtx a_nan = gen_reg_rtx (V4SImode);
2805 rtx a_abs = gen_reg_rtx (V4SImode);
2806 rtx b_abs = gen_reg_rtx (V4SImode);
2807 rtx iszero = gen_reg_rtx (V4SImode);
2808 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
2809 0x7FFFFFFF, 0xFFFFFFFF);
2810 rtx sign_mask = gen_reg_rtx (V4SImode);
2811 rtx nan_mask = gen_reg_rtx (V4SImode);
2812 rtx hihi_promote = gen_reg_rtx (TImode);
2814 emit_move_insn (sign_mask, pat);
2815 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
2817 emit_move_insn (nan_mask, pat);
2818 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
2819 0x08090A0B, 0x18191A1B);
2820 emit_move_insn (hihi_promote, pat);
2822 emit_insn (gen_ceq_v4si (biteq, ra, rb));
2823 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
2825 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
2826 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
2827 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
2828 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
2829 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
2830 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
2832 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
2833 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
2834 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
2835 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
2836 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
2838 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
2839 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
2840 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
2841 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
2846 (define_expand "cmeq_v2df"
2847 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
2848 (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
2849 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
2852 if (spu_arch == PROCESSOR_CELL)
2854 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
2855 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
2856 rtx temp = gen_reg_rtx (TImode);
2857 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2858 rtx temp2 = gen_reg_rtx (V4SImode);
2859 rtx biteq = gen_reg_rtx (V4SImode);
2860 rtx ahi_inf = gen_reg_rtx (V4SImode);
2861 rtx a_nan = gen_reg_rtx (V4SImode);
2862 rtx a_abs = gen_reg_rtx (V4SImode);
2863 rtx b_abs = gen_reg_rtx (V4SImode);
2865 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
2866 0x7FFFFFFF, 0xFFFFFFFF);
2867 rtx sign_mask = gen_reg_rtx (V4SImode);
2868 rtx nan_mask = gen_reg_rtx (V4SImode);
2869 rtx hihi_promote = gen_reg_rtx (TImode);
2871 emit_move_insn (sign_mask, pat);
2873 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
2875 emit_move_insn (nan_mask, pat);
2876 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
2877 0x08090A0B, 0x18191A1B);
2878 emit_move_insn (hihi_promote, pat);
2880 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
2881 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
2882 emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
2883 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
2885 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
2886 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
2887 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
2888 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
2890 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
2891 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
2892 emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
2893 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
2901 (define_insn "cgt_<mode>"
2902 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2903 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2904 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2908 cgt<bh>i\t%0,%1,%2")
2910 (define_insn "cgt_di_m1"
2911 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2912 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2917 (define_insn_and_split "cgt_di"
2918 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2919 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2920 (match_operand:DI 2 "spu_reg_operand" "r")))
2921 (clobber (match_scratch:V4SI 3 "=&r"))
2922 (clobber (match_scratch:V4SI 4 "=&r"))
2923 (clobber (match_scratch:V4SI 5 "=&r"))]
2927 [(set (match_dup:SI 0)
2928 (gt:SI (match_dup:DI 1)
2931 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2932 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2933 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2934 rtx op3 = operands[3];
2935 rtx op4 = operands[4];
2936 rtx op5 = operands[5];
2937 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
2938 emit_insn (gen_clgt_v4si (op3, op1, op2));
2939 emit_insn (gen_ceq_v4si (op4, op1, op2));
2940 emit_insn (gen_cgt_v4si (op5, op1, op2));
2941 emit_insn (gen_spu_xswd (op3d, op3));
2942 emit_insn (gen_selb (op0, op5, op3, op4));
2946 (define_insn "cgt_ti"
2947 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2948 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
2949 (match_operand:TI 2 "spu_reg_operand" "r")))
2950 (clobber (match_scratch:V4SI 3 "=&r"))
2951 (clobber (match_scratch:V4SI 4 "=&r"))
2952 (clobber (match_scratch:V4SI 5 "=&r"))]
2958 selb\t%0,%4,%0,%3\;\
2960 selb\t%0,%4,%0,%3\;\
2963 [(set_attr "type" "multi0")
2964 (set_attr "length" "36")])
2966 (define_insn "cgt_<mode>"
2967 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2968 (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
2969 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2973 (define_insn "cmgt_<mode>"
2974 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2975 (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2976 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2980 (define_expand "cgt_df"
2981 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2982 (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
2983 (match_operand:DF 2 "const_zero_operand" "i")))]
2986 if (spu_arch == PROCESSOR_CELL)
2988 rtx ra = gen_reg_rtx (V4SImode);
2989 rtx rb = gen_reg_rtx (V4SImode);
2990 rtx zero = gen_reg_rtx (V4SImode);
2991 rtx temp = gen_reg_rtx (TImode);
2992 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2993 rtx temp2 = gen_reg_rtx (V4SImode);
2994 rtx hi_inf = gen_reg_rtx (V4SImode);
2995 rtx a_nan = gen_reg_rtx (V4SImode);
2996 rtx b_nan = gen_reg_rtx (V4SImode);
2997 rtx a_abs = gen_reg_rtx (V4SImode);
2998 rtx b_abs = gen_reg_rtx (V4SImode);
2999 rtx asel = gen_reg_rtx (V4SImode);
3000 rtx bsel = gen_reg_rtx (V4SImode);
3001 rtx abor = gen_reg_rtx (V4SImode);
3002 rtx bbor = gen_reg_rtx (V4SImode);
3003 rtx gt_hi = gen_reg_rtx (V4SImode);
3004 rtx gt_lo = gen_reg_rtx (V4SImode);
3005 rtx sign_mask = gen_reg_rtx (V4SImode);
3006 rtx nan_mask = gen_reg_rtx (V4SImode);
3007 rtx hi_promote = gen_reg_rtx (TImode);
3008 rtx borrow_shuffle = gen_reg_rtx (TImode);
3010 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3011 0x7FFFFFFF, 0xFFFFFFFF);
3012 emit_move_insn (sign_mask, pat);
3013 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3015 emit_move_insn (nan_mask, pat);
3016 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3017 0x08090A0B, 0x08090A0B);
3018 emit_move_insn (hi_promote, pat);
3019 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3020 0x0C0D0E0F, 0xC0C0C0C0);
3021 emit_move_insn (borrow_shuffle, pat);
3023 emit_insn (gen_spu_convert (ra, operands[1]));
3024 emit_insn (gen_spu_convert (rb, operands[2]));
3025 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3026 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3028 if (!flag_finite_math_only)
3030 /* check if ra is NaN */
3031 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3032 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3033 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3035 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3036 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3037 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3039 /* check if rb is NaN */
3040 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3041 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3042 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3044 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3045 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3046 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3048 /* check if ra or rb is NaN */
3049 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3051 emit_move_insn (zero, CONST0_RTX (V4SImode));
3052 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3053 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3054 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3055 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3056 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3057 emit_insn (gen_selb (abor, a_abs, abor, asel));
3059 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3060 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3061 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3062 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3063 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3064 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3066 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3067 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3068 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3069 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3071 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3072 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3073 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3074 if (!flag_finite_math_only)
3076 /* correct for NaNs */
3077 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3079 emit_insn (gen_spu_convert (operands[0], temp2));
3084 (define_insn "cgt_<mode>_celledp"
3085 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3086 (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3087 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3088 "spu_arch == PROCESSOR_CELLEDP"
3090 [(set_attr "type" "fpd")])
3092 (define_insn "cmgt_<mode>_celledp"
3093 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3094 (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3095 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3096 "spu_arch == PROCESSOR_CELLEDP"
3098 [(set_attr "type" "fpd")])
3100 (define_expand "cgt_v2df"
3101 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3102 (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3103 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3106 if (spu_arch == PROCESSOR_CELL)
3108 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3109 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3110 rtx zero = gen_reg_rtx (V4SImode);
3111 rtx temp = gen_reg_rtx (TImode);
3112 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3113 rtx temp2 = gen_reg_rtx (V4SImode);
3114 rtx hi_inf = gen_reg_rtx (V4SImode);
3115 rtx a_nan = gen_reg_rtx (V4SImode);
3116 rtx b_nan = gen_reg_rtx (V4SImode);
3117 rtx a_abs = gen_reg_rtx (V4SImode);
3118 rtx b_abs = gen_reg_rtx (V4SImode);
3119 rtx asel = gen_reg_rtx (V4SImode);
3120 rtx bsel = gen_reg_rtx (V4SImode);
3121 rtx abor = gen_reg_rtx (V4SImode);
3122 rtx bbor = gen_reg_rtx (V4SImode);
3123 rtx gt_hi = gen_reg_rtx (V4SImode);
3124 rtx gt_lo = gen_reg_rtx (V4SImode);
3125 rtx sign_mask = gen_reg_rtx (V4SImode);
3126 rtx nan_mask = gen_reg_rtx (V4SImode);
3127 rtx hi_promote = gen_reg_rtx (TImode);
3128 rtx borrow_shuffle = gen_reg_rtx (TImode);
3129 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3130 0x7FFFFFFF, 0xFFFFFFFF);
3131 emit_move_insn (sign_mask, pat);
3132 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3134 emit_move_insn (nan_mask, pat);
3135 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3136 0x08090A0B, 0x08090A0B);
3137 emit_move_insn (hi_promote, pat);
3138 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3139 0x0C0D0E0F, 0xC0C0C0C0);
3140 emit_move_insn (borrow_shuffle, pat);
3142 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3143 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3144 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3145 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3147 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3148 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3149 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3150 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3151 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3152 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3153 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3155 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3156 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3157 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3158 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3159 emit_move_insn (zero, CONST0_RTX (V4SImode));
3160 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3161 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3162 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3163 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3164 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3165 emit_insn (gen_selb (abor, a_abs, abor, asel));
3166 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3167 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3168 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3169 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3170 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3171 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3172 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3173 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3174 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3175 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3177 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3178 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3180 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3181 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3182 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3187 (define_expand "cmgt_v2df"
3188 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3189 (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3190 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3193 if (spu_arch == PROCESSOR_CELL)
3195 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3196 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3197 rtx temp = gen_reg_rtx (TImode);
3198 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3199 rtx temp2 = gen_reg_rtx (V4SImode);
3200 rtx hi_inf = gen_reg_rtx (V4SImode);
3201 rtx a_nan = gen_reg_rtx (V4SImode);
3202 rtx b_nan = gen_reg_rtx (V4SImode);
3203 rtx a_abs = gen_reg_rtx (V4SImode);
3204 rtx b_abs = gen_reg_rtx (V4SImode);
3205 rtx gt_hi = gen_reg_rtx (V4SImode);
3206 rtx gt_lo = gen_reg_rtx (V4SImode);
3207 rtx sign_mask = gen_reg_rtx (V4SImode);
3208 rtx nan_mask = gen_reg_rtx (V4SImode);
3209 rtx hi_promote = gen_reg_rtx (TImode);
3210 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3211 0x7FFFFFFF, 0xFFFFFFFF);
3212 emit_move_insn (sign_mask, pat);
3213 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3215 emit_move_insn (nan_mask, pat);
3216 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3217 0x08090A0B, 0x08090A0B);
3218 emit_move_insn (hi_promote, pat);
3220 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3221 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3222 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3223 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3225 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3226 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3227 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3228 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3229 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3230 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3231 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3233 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3234 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3235 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3236 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3238 emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3239 emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3240 emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3241 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3243 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3244 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3245 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3246 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3247 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3255 (define_insn "clgt_<mode>"
3256 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3257 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3258 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3262 clgt<bh>i\t%0,%1,%2")
3264 (define_insn_and_split "clgt_di"
3265 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3266 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3267 (match_operand:DI 2 "spu_reg_operand" "r")))
3268 (clobber (match_scratch:V4SI 3 "=&r"))
3269 (clobber (match_scratch:V4SI 4 "=&r"))
3270 (clobber (match_scratch:V4SI 5 "=&r"))]
3274 [(set (match_dup:SI 0)
3275 (gtu:SI (match_dup:DI 1)
3278 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3279 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3280 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3281 rtx op3 = operands[3];
3282 rtx op4 = operands[4];
3283 rtx op5 = operands[5];
3284 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3285 emit_insn (gen_clgt_v4si (op3, op1, op2));
3286 emit_insn (gen_ceq_v4si (op4, op1, op2));
3287 emit_insn (gen_spu_xswd (op5d, op3));
3288 emit_insn (gen_selb (op0, op3, op5, op4));
3292 (define_insn "clgt_ti"
3293 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3294 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3295 (match_operand:TI 2 "spu_reg_operand" "r")))
3296 (clobber (match_scratch:V4SI 3 "=&r"))
3297 (clobber (match_scratch:V4SI 4 "=&r"))]
3302 selb\t%0,%4,%0,%3\;\
3304 selb\t%0,%4,%0,%3\;\
3307 [(set_attr "type" "multi0")
3308 (set_attr "length" "32")])
3312 (define_insn "dftsv_celledp"
3313 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3314 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3315 (match_operand:SI 2 "const_int_operand" "i")]
3317 "spu_arch == PROCESSOR_CELLEDP"
3319 [(set_attr "type" "fpd")])
3321 (define_expand "dftsv"
3322 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3323 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3324 (match_operand:SI 2 "const_int_operand" "i")]
3328 if (spu_arch == PROCESSOR_CELL)
3330 rtx result = gen_reg_rtx (V4SImode);
3331 emit_move_insn (result, CONST0_RTX (V4SImode));
3333 if (INTVAL (operands[2]))
3335 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3336 rtx abs = gen_reg_rtx (V4SImode);
3337 rtx sign = gen_reg_rtx (V4SImode);
3338 rtx temp = gen_reg_rtx (TImode);
3339 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3340 rtx temp2 = gen_reg_rtx (V4SImode);
3341 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3342 0x7FFFFFFF, 0xFFFFFFFF);
3343 rtx sign_mask = gen_reg_rtx (V4SImode);
3344 rtx hi_promote = gen_reg_rtx (TImode);
3345 emit_move_insn (sign_mask, pat);
3346 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3347 0x08090A0B, 0x08090A0B);
3348 emit_move_insn (hi_promote, pat);
3350 emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3351 emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3352 emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3354 /* NaN or +inf or -inf */
3355 if (INTVAL (operands[2]) & 0x70)
3357 rtx nan_mask = gen_reg_rtx (V4SImode);
3358 rtx isinf = gen_reg_rtx (V4SImode);
3359 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3361 emit_move_insn (nan_mask, pat);
3362 emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3365 if (INTVAL (operands[2]) & 0x40)
3367 rtx isnan = gen_reg_rtx (V4SImode);
3368 emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3369 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3371 emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3372 emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3373 emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3374 emit_insn (gen_iorv4si3 (result, result, isnan));
3377 if (INTVAL (operands[2]) & 0x30)
3379 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3381 emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3382 emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3385 if (INTVAL (operands[2]) & 0x20)
3387 emit_insn (gen_andc_v4si (temp2, isinf, sign));
3388 emit_insn (gen_iorv4si3 (result, result, temp2));
3391 if (INTVAL (operands[2]) & 0x10)
3393 emit_insn (gen_andv4si3 (temp2, isinf, sign));
3394 emit_insn (gen_iorv4si3 (result, result, temp2));
3400 if (INTVAL (operands[2]) & 0xF)
3402 rtx iszero = gen_reg_rtx (V4SImode);
3403 emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3404 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3406 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3409 if (INTVAL (operands[2]) & 0x3)
3411 rtx isdenorm = gen_reg_rtx (V4SImode);
3412 rtx denorm_mask = gen_reg_rtx (V4SImode);
3413 emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3414 emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3415 emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3416 emit_insn (gen_shufb (isdenorm, isdenorm,
3417 isdenorm, hi_promote));
3419 if (INTVAL (operands[2]) & 0x2)
3421 emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3422 emit_insn (gen_iorv4si3 (result, result, temp2));
3425 if (INTVAL (operands[2]) & 0x1)
3427 emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3428 emit_insn (gen_iorv4si3 (result, result, temp2));
3433 if (INTVAL (operands[2]) & 0xC)
3435 emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3437 if (INTVAL (operands[2]) & 0x8)
3439 emit_insn (gen_andc_v4si (temp2, iszero, sign));
3440 emit_insn (gen_iorv4si3 (result, result, temp2));
3443 if (INTVAL (operands[2]) & 0x4)
3445 emit_insn (gen_andv4si3 (temp2, iszero, sign));
3446 emit_insn (gen_iorv4si3 (result, result, temp2));
3451 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3461 (if_then_else (match_operator 1 "branch_comparison_operator"
3463 "spu_reg_operand" "r")
3465 (label_ref (match_operand 0 "" ""))
3469 [(set_attr "type" "br")])
3473 (if_then_else (match_operator 0 "branch_comparison_operator"
3475 "spu_reg_operand" "r")
3481 [(set_attr "type" "br")])
3485 (if_then_else (match_operator 1 "branch_comparison_operator"
3487 "spu_reg_operand" "r")
3490 (label_ref (match_operand 0 "" ""))))]
3493 [(set_attr "type" "br")])
3497 (if_then_else (match_operator 0 "branch_comparison_operator"
3499 "spu_reg_operand" "r")
3505 [(set_attr "type" "br")])
3508 ;; Compare insns are next. Note that the spu has two types of compares,
3509 ;; signed & unsigned, and one type of branch.
3511 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
3512 ;; insns, and branches. We store the operands of compares until we see
3515 (define_expand "cmp<mode>"
3517 (compare (match_operand:VQHSI 0 "spu_reg_operand" "")
3518 (match_operand:VQHSI 1 "spu_nonmem_operand" "")))]
3521 spu_compare_op0 = operands[0];
3522 spu_compare_op1 = operands[1];
3526 (define_expand "cmp<mode>"
3528 (compare (match_operand:DTI 0 "spu_reg_operand" "")
3529 (match_operand:DTI 1 "spu_reg_operand" "")))]
3532 spu_compare_op0 = operands[0];
3533 spu_compare_op1 = operands[1];
3537 (define_expand "cmp<mode>"
3539 (compare (match_operand:VSF 0 "spu_reg_operand" "")
3540 (match_operand:VSF 1 "spu_reg_operand" "")))]
3543 spu_compare_op0 = operands[0];
3544 spu_compare_op1 = operands[1];
3548 (define_expand "cmpdf"
3550 (compare (match_operand:DF 0 "register_operand" "")
3551 (match_operand:DF 1 "register_operand" "")))]
3554 spu_compare_op0 = operands[0];
3555 spu_compare_op1 = operands[1];
3559 ;; vector conditional compare patterns
3560 (define_expand "vcond<mode>"
3561 [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3563 (match_operator 3 "comparison_operator"
3564 [(match_operand:VCMP 4 "spu_reg_operand" "r")
3565 (match_operand:VCMP 5 "spu_reg_operand" "r")])
3566 (match_operand:VCMP 1 "spu_reg_operand" "r")
3567 (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3570 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3571 operands[3], operands[4], operands[5]))
3577 (define_expand "vcondu<mode>"
3578 [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3580 (match_operator 3 "comparison_operator"
3581 [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3582 (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3583 (match_operand:VCMPU 1 "spu_reg_operand" "r")
3584 (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3587 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3588 operands[3], operands[4], operands[5]))
3595 ;; branch on condition
3597 (define_expand "beq"
3598 [(use (match_operand 0 "" ""))]
3600 { spu_emit_branch_or_set (0, EQ, operands); DONE; })
3602 (define_expand "bne"
3603 [(use (match_operand 0 "" ""))]
3605 { spu_emit_branch_or_set (0, NE, operands); DONE; })
3607 (define_expand "bge"
3608 [(use (match_operand 0 "" ""))]
3610 { spu_emit_branch_or_set (0, GE, operands); DONE; })
3612 (define_expand "bgt"
3613 [(use (match_operand 0 "" ""))]
3615 { spu_emit_branch_or_set (0, GT, operands); DONE; })
3617 (define_expand "ble"
3618 [(use (match_operand 0 "" ""))]
3620 { spu_emit_branch_or_set (0, LE, operands); DONE; })
3622 (define_expand "blt"
3623 [(use (match_operand 0 "" ""))]
3625 { spu_emit_branch_or_set (0, LT, operands); DONE; })
3627 (define_expand "bgeu"
3628 [(use (match_operand 0 "" ""))]
3630 { spu_emit_branch_or_set (0, GEU, operands); DONE; })
3632 (define_expand "bgtu"
3633 [(use (match_operand 0 "" ""))]
3635 { spu_emit_branch_or_set (0, GTU, operands); DONE; })
3637 (define_expand "bleu"
3638 [(use (match_operand 0 "" ""))]
3640 { spu_emit_branch_or_set (0, LEU, operands); DONE; })
3642 (define_expand "bltu"
3643 [(use (match_operand 0 "" ""))]
3645 { spu_emit_branch_or_set (0, LTU, operands); DONE; })
3650 (define_expand "seq"
3651 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3653 { spu_emit_branch_or_set (1, EQ, operands); DONE; })
3655 (define_expand "sne"
3656 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3658 { spu_emit_branch_or_set (1, NE, operands); DONE; })
3660 (define_expand "sgt"
3661 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3663 { spu_emit_branch_or_set (1, GT, operands); DONE; })
3665 (define_expand "slt"
3666 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3668 { spu_emit_branch_or_set (1, LT, operands); DONE; })
3670 (define_expand "sge"
3671 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3673 { spu_emit_branch_or_set (1, GE, operands); DONE; })
3675 (define_expand "sle"
3676 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3678 { spu_emit_branch_or_set (1, LE, operands); DONE; })
3680 (define_expand "sgtu"
3681 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3683 { spu_emit_branch_or_set (1, GTU, operands); DONE; })
3685 (define_expand "sltu"
3686 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3688 { spu_emit_branch_or_set (1, LTU, operands); DONE; })
3690 (define_expand "sgeu"
3691 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3693 { spu_emit_branch_or_set (1, GEU, operands); DONE; })
3695 (define_expand "sleu"
3696 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
3698 { spu_emit_branch_or_set (1, LEU, operands); DONE; })
3703 ;; Define this first one so HAVE_conditional_move is defined.
3704 (define_insn "movcc_dummy"
3705 [(set (match_operand 0 "" "")
3706 (if_then_else (match_operand 1 "" "")
3707 (match_operand 2 "" "")
3708 (match_operand 3 "" "")))]
3712 (define_expand "mov<mode>cc"
3713 [(set (match_operand:ALL 0 "spu_reg_operand" "")
3714 (if_then_else:ALL (match_operand 1 "comparison_operator" "")
3715 (match_operand:ALL 2 "spu_reg_operand" "")
3716 (match_operand:ALL 3 "spu_reg_operand" "")))]
3719 spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
3723 ;; This pattern is used when the result of a compare is not large
3724 ;; enough to use in a selb when expanding conditional moves.
3725 (define_expand "extend_compare"
3726 [(set (match_operand 0 "spu_reg_operand" "=r")
3727 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3730 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3731 gen_rtx_UNSPEC (GET_MODE (operands[0]),
3732 gen_rtvec (1, operands[1]),
3733 UNSPEC_EXTEND_CMP)));
3737 (define_insn "extend_compare<mode>"
3738 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
3739 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3742 [(set_attr "type" "shuf")])
3747 ;; operand 0 is index
3748 ;; operand 1 is the minimum bound
3749 ;; operand 2 is the maximum bound - minimum bound + 1
3750 ;; operand 3 is CODE_LABEL for the table;
3751 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3752 (define_expand "casesi"
3753 [(match_operand:SI 0 "spu_reg_operand" "")
3754 (match_operand:SI 1 "immediate_operand" "")
3755 (match_operand:SI 2 "immediate_operand" "")
3756 (match_operand 3 "" "")
3757 (match_operand 4 "" "")]
3760 rtx table = gen_reg_rtx (SImode);
3761 rtx index = gen_reg_rtx (SImode);
3762 rtx sindex = gen_reg_rtx (SImode);
3763 rtx addr = gen_reg_rtx (Pmode);
3765 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
3767 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
3768 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
3769 emit_move_insn (addr, gen_rtx_MEM (SImode,
3770 gen_rtx_PLUS (SImode, table, sindex)));
3772 emit_insn (gen_addsi3 (addr, addr, table));
3774 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
3775 emit_jump_insn (gen_tablejump (addr, operands[3]));
3779 (define_insn "tablejump"
3780 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
3781 (use (label_ref (match_operand 1 "" "")))]
3784 [(set_attr "type" "br")])
3789 ;; Note that operand 1 is total size of args, in bytes,
3790 ;; and what the call insn wants is the number of words.
3791 (define_expand "sibcall"
3793 [(call (match_operand:QI 0 "call_operand" "")
3794 (match_operand:QI 1 "" ""))
3798 if (! call_operand (operands[0], QImode))
3799 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3802 (define_insn "_sibcall"
3804 [(call (match_operand:QI 0 "call_operand" "R,S")
3805 (match_operand:QI 1 "" "i,i"))
3807 "SIBLING_CALL_P(insn)"
3811 [(set_attr "type" "br,br")])
3813 (define_expand "sibcall_value"
3815 [(set (match_operand 0 "" "")
3816 (call (match_operand:QI 1 "call_operand" "")
3817 (match_operand:QI 2 "" "")))
3821 if (! call_operand (operands[1], QImode))
3822 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3825 (define_insn "_sibcall_value"
3827 [(set (match_operand 0 "" "")
3828 (call (match_operand:QI 1 "call_operand" "R,S")
3829 (match_operand:QI 2 "" "i,i")))
3831 "SIBLING_CALL_P(insn)"
3835 [(set_attr "type" "br,br")])
3837 ;; Note that operand 1 is total size of args, in bytes,
3838 ;; and what the call insn wants is the number of words.
3839 (define_expand "call"
3841 [(call (match_operand:QI 0 "call_operand" "")
3842 (match_operand:QI 1 "" ""))
3843 (clobber (reg:SI 0))
3844 (clobber (reg:SI 130))])]
3847 if (! call_operand (operands[0], QImode))
3848 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3851 (define_insn "_call"
3853 [(call (match_operand:QI 0 "call_operand" "R,S,T")
3854 (match_operand:QI 1 "" "i,i,i"))
3855 (clobber (reg:SI 0))
3856 (clobber (reg:SI 130))])]
3862 [(set_attr "type" "br")])
3864 (define_expand "call_value"
3866 [(set (match_operand 0 "" "")
3867 (call (match_operand:QI 1 "call_operand" "")
3868 (match_operand:QI 2 "" "")))
3869 (clobber (reg:SI 0))
3870 (clobber (reg:SI 130))])]
3873 if (! call_operand (operands[1], QImode))
3874 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3877 (define_insn "_call_value"
3879 [(set (match_operand 0 "" "")
3880 (call (match_operand:QI 1 "call_operand" "R,S,T")
3881 (match_operand:QI 2 "" "i,i,i")))
3882 (clobber (reg:SI 0))
3883 (clobber (reg:SI 130))])]
3889 [(set_attr "type" "br")])
3891 (define_expand "untyped_call"
3892 [(parallel [(call (match_operand 0 "" "")
3894 (match_operand 1 "" "")
3895 (match_operand 2 "" "")])]
3899 rtx reg = gen_rtx_REG (TImode, 3);
3901 /* We need to use call_value so the return value registers don't get
3903 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
3905 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3907 rtx set = XVECEXP (operands[2], 0, i);
3908 emit_move_insn (SET_DEST (set), SET_SRC (set));
3911 /* The optimizer does not know that the call sets the function value
3912 registers we stored in the result block. We avoid problems by
3913 claiming that all hard registers are used and clobbered at this
3915 emit_insn (gen_blockage ());
3921 ;; Patterns used for splitting and combining.
3924 ;; Function prologue and epilogue.
3926 (define_expand "prologue"
3929 { spu_expand_prologue (); DONE; })
3931 ;; "blockage" is only emited in epilogue. This is what it took to
3932 ;; make "basic block reordering" work with the insns sequence
3933 ;; generated by the spu_expand_epilogue (taken from mips.md)
3935 (define_insn "blockage"
3936 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
3939 [(set_attr "type" "convert")
3940 (set_attr "length" "0")])
3942 (define_expand "epilogue"
3945 { spu_expand_epilogue (false); DONE; })
3947 (define_expand "sibcall_epilogue"
3950 { spu_expand_epilogue (true); DONE; })
3953 ;; stack manipulations
3955 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
3956 ;; We move the back-chain and decrement the stack pointer.
3957 (define_expand "allocate_stack"
3958 [(set (match_operand 0 "spu_reg_operand" "")
3959 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
3961 (minus (reg 1) (match_dup 1)))]
3963 "spu_allocate_stack (operands[0], operands[1]); DONE;")
3965 ;; These patterns say how to save and restore the stack pointer. We need not
3966 ;; save the stack pointer at function level since we are careful to preserve
3970 ;; At block level the stack pointer is saved and restored, so that the
3971 ;; stack space allocated within a block is deallocated when leaving
3972 ;; block scope. By default, according to the SPU ABI, the stack
3973 ;; pointer and available stack size are saved in a register. Upon
3974 ;; restoration, the stack pointer is simply copied back, and the
3975 ;; current available stack size is calculated against the restored
3978 ;; For nonlocal gotos, we must save the stack pointer and its
3979 ;; backchain and restore both. Note that in the nonlocal case, the
3980 ;; save area is a memory location.
3982 (define_expand "save_stack_function"
3983 [(match_operand 0 "general_operand" "")
3984 (match_operand 1 "general_operand" "")]
3988 (define_expand "restore_stack_function"
3989 [(match_operand 0 "general_operand" "")
3990 (match_operand 1 "general_operand" "")]
3994 (define_expand "restore_stack_block"
3995 [(match_operand 0 "spu_reg_operand" "")
3996 (match_operand 1 "memory_operand" "")]
4000 spu_restore_stack_block (operands[0], operands[1]);
4004 (define_expand "save_stack_nonlocal"
4005 [(match_operand 0 "memory_operand" "")
4006 (match_operand 1 "spu_reg_operand" "")]
4010 rtx temp = gen_reg_rtx (Pmode);
4012 /* Copy the backchain to the first word, sp to the second. We need to
4013 save the back chain because __builtin_apply appears to clobber it. */
4014 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4015 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4016 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4020 (define_expand "restore_stack_nonlocal"
4021 [(match_operand 0 "spu_reg_operand" "")
4022 (match_operand 1 "memory_operand" "")]
4026 spu_restore_stack_nonlocal(operands[0], operands[1]);
4033 ;; Vector initialization
4034 (define_expand "vec_init<mode>"
4035 [(match_operand:V 0 "register_operand" "")
4036 (match_operand 1 "" "")]
4039 spu_expand_vector_init (operands[0], operands[1]);
4043 (define_expand "vec_set<mode>"
4044 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4045 (set (match_dup:TI 3)
4046 (unspec:TI [(match_dup:SI 4)
4048 (match_dup:SI 6)] UNSPEC_CPAT))
4049 (set (match_operand:V 0 "spu_reg_operand" "")
4050 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4052 (match_dup:TI 3)] UNSPEC_SHUFB))]
4055 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4056 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4057 operands[3] = gen_reg_rtx (TImode);
4058 operands[4] = stack_pointer_rtx;
4059 operands[5] = offset;
4060 operands[6] = GEN_INT (size);
4063 (define_expand "vec_extract<mode>"
4064 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4065 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4066 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4069 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4071 emit_insn (gen_spu_convert (operands[0], operands[1]));
4076 (define_insn "_vec_extract<mode>"
4077 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4078 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4079 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4081 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4082 [(set_attr "type" "shuf")])
4084 (define_insn "_vec_extractv8hi_ze"
4085 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4086 (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4087 (parallel [(const_int 0)]))))]
4089 "rotqmbyi\t%0,%1,-2"
4090 [(set_attr "type" "shuf")])
4095 (define_expand "shufb"
4096 [(set (match_operand 0 "spu_reg_operand" "")
4097 (unspec [(match_operand 1 "spu_reg_operand" "")
4098 (match_operand 2 "spu_reg_operand" "")
4099 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4102 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4103 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4108 (define_insn "_shufb"
4109 [(set (match_operand 0 "spu_reg_operand" "=r")
4110 (unspec [(match_operand 1 "spu_reg_operand" "r")
4111 (match_operand 2 "spu_reg_operand" "r")
4112 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4114 "shufb\t%0,%1,%2,%3"
4115 [(set_attr "type" "shuf")])
4118 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4121 [(set_attr "type" "nop")])
4124 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4127 [(set_attr "type" "nop")])
4130 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4133 [(set_attr "type" "lnop")])
4135 (define_insn "iprefetch"
4136 [(unspec [(const_int 0)] UNSPEC_IPREFETCH)]
4139 [(set_attr "type" "iprefetch")])
4143 (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4144 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4145 (unspec [(const_int 0)] UNSPEC_HBR)]
4151 [(set_attr "type" "hbr")])
4154 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4155 (clobber (mem:BLK (scratch)))]
4158 [(set_attr "type" "br")])
4160 (define_insn "syncc"
4161 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4162 (clobber (mem:BLK (scratch)))]
4165 [(set_attr "type" "br")])
4167 (define_insn "dsync"
4168 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4169 (clobber (mem:BLK (scratch)))]
4172 [(set_attr "type" "br")])
4176 ;; Define the subtract-one-and-jump insns so loop.c
4177 ;; knows what to generate.
4178 (define_expand "doloop_end"
4179 [(use (match_operand 0 "" "")) ; loop pseudo
4180 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4181 (use (match_operand 2 "" "")) ; max iterations
4182 (use (match_operand 3 "" "")) ; loop level
4183 (use (match_operand 4 "" ""))] ; label
4187 /* Currently SMS relies on the do-loop pattern to recognize loops
4188 where (1) the control part comprises of all insns defining and/or
4189 using a certain 'count' register and (2) the loop count can be
4190 adjusted by modifying this register prior to the loop.
4191 . ??? The possible introduction of a new block to initialize the
4192 new IV can potentially effects branch optimizations. */
4193 if (optimize > 0 && flag_modulo_sched)
4199 /* Only use this on innermost loops. */
4200 if (INTVAL (operands[3]) > 1)
4202 if (GET_MODE (operands[0]) != SImode)
4206 emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4207 bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4208 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4209 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4210 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4218 ;; convert between any two modes, avoiding any GCC assumptions
4219 (define_expand "spu_convert"
4220 [(set (match_operand 0 "spu_reg_operand" "")
4221 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4224 rtx c = gen__spu_convert (operands[0], operands[1]);
4225 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4230 (define_insn "_spu_convert"
4231 [(set (match_operand 0 "spu_reg_operand" "=r")
4232 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4235 [(set_attr "type" "convert")
4236 (set_attr "length" "0")])
4239 [(set (match_operand 0 "spu_reg_operand")
4240 (unspec [(match_operand 1 "spu_reg_operand")] UNSPEC_CONVERT))]
4242 [(use (const_int 0))]
4247 (include "spu-builtins.md")
4250 (define_expand "smaxv4sf3"
4251 [(set (match_operand:V4SF 0 "register_operand" "=r")
4252 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4253 (match_operand:V4SF 2 "register_operand" "r")))]
4257 rtx mask = gen_reg_rtx (V4SImode);
4259 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4260 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4264 (define_expand "sminv4sf3"
4265 [(set (match_operand:V4SF 0 "register_operand" "=r")
4266 (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4267 (match_operand:V4SF 2 "register_operand" "r")))]
4271 rtx mask = gen_reg_rtx (V4SImode);
4273 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4274 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4278 (define_expand "smaxv2df3"
4279 [(set (match_operand:V2DF 0 "register_operand" "=r")
4280 (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4281 (match_operand:V2DF 2 "register_operand" "r")))]
4285 rtx mask = gen_reg_rtx (V2DImode);
4286 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4287 emit_insn (gen_selb (operands[0], operands[2], operands[1],
4288 spu_gen_subreg (V4SImode, mask)));
4292 (define_expand "sminv2df3"
4293 [(set (match_operand:V2DF 0 "register_operand" "=r")
4294 (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4295 (match_operand:V2DF 2 "register_operand" "r")))]
4299 rtx mask = gen_reg_rtx (V2DImode);
4300 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4301 emit_insn (gen_selb (operands[0], operands[1], operands[2],
4302 spu_gen_subreg (V4SImode, mask)));
4306 (define_expand "vec_widen_umult_hi_v8hi"
4307 [(set (match_operand:V4SI 0 "register_operand" "=r")
4311 (match_operand:V8HI 1 "register_operand" "r")
4312 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4315 (match_operand:V8HI 2 "register_operand" "r")
4316 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4320 rtx ve = gen_reg_rtx (V4SImode);
4321 rtx vo = gen_reg_rtx (V4SImode);
4322 rtx mask = gen_reg_rtx (TImode);
4323 unsigned char arr[16] = {
4324 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4325 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4327 emit_move_insn (mask, array_to_constant (TImode, arr));
4328 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4329 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4330 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4334 (define_expand "vec_widen_umult_lo_v8hi"
4335 [(set (match_operand:V4SI 0 "register_operand" "=r")
4339 (match_operand:V8HI 1 "register_operand" "r")
4340 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4343 (match_operand:V8HI 2 "register_operand" "r")
4344 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4348 rtx ve = gen_reg_rtx (V4SImode);
4349 rtx vo = gen_reg_rtx (V4SImode);
4350 rtx mask = gen_reg_rtx (TImode);
4351 unsigned char arr[16] = {
4352 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4353 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4355 emit_move_insn (mask, array_to_constant (TImode, arr));
4356 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4357 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4358 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4362 (define_expand "vec_widen_smult_hi_v8hi"
4363 [(set (match_operand:V4SI 0 "register_operand" "=r")
4367 (match_operand:V8HI 1 "register_operand" "r")
4368 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4371 (match_operand:V8HI 2 "register_operand" "r")
4372 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4376 rtx ve = gen_reg_rtx (V4SImode);
4377 rtx vo = gen_reg_rtx (V4SImode);
4378 rtx mask = gen_reg_rtx (TImode);
4379 unsigned char arr[16] = {
4380 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4381 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4383 emit_move_insn (mask, array_to_constant (TImode, arr));
4384 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4385 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4386 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4390 (define_expand "vec_widen_smult_lo_v8hi"
4391 [(set (match_operand:V4SI 0 "register_operand" "=r")
4395 (match_operand:V8HI 1 "register_operand" "r")
4396 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4399 (match_operand:V8HI 2 "register_operand" "r")
4400 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4404 rtx ve = gen_reg_rtx (V4SImode);
4405 rtx vo = gen_reg_rtx (V4SImode);
4406 rtx mask = gen_reg_rtx (TImode);
4407 unsigned char arr[16] = {
4408 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4409 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4411 emit_move_insn (mask, array_to_constant (TImode, arr));
4412 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4413 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4414 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4418 (define_expand "vec_realign_load_<mode>"
4419 [(set (match_operand:ALL 0 "register_operand" "=r")
4420 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4421 (match_operand:ALL 2 "register_operand" "r")
4422 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4426 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4430 (define_expand "spu_lvsr"
4431 [(set (match_operand:V16QI 0 "register_operand" "")
4432 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4437 rtx offset = gen_reg_rtx (V8HImode);
4438 rtx addr_bits = gen_reg_rtx (SImode);
4439 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4440 rtx splatqi = gen_reg_rtx (TImode);
4441 rtx result = gen_reg_rtx (V8HImode);
4442 unsigned char arr[16] = {
4443 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4444 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4445 unsigned char arr2[16] = {
4446 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4447 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4449 emit_move_insn (offset, array_to_constant (V8HImode, arr));
4450 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4452 gcc_assert (GET_CODE (operands[1]) == MEM);
4453 addr = force_reg (Pmode, XEXP (operands[1], 0));
4454 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4455 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4457 /* offset - (addr & 0xF)
4458 It is safe to use a single sfh, because each byte of offset is > 15 and
4459 each byte of addr is <= 15. */
4460 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4462 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4463 emit_move_insn (operands[0], result);
4468 (define_expand "vec_unpacku_hi_v8hi"
4469 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4472 (match_operand:V8HI 1 "spu_reg_operand" "r")
4473 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4476 rtx mask = gen_reg_rtx (TImode);
4477 unsigned char arr[16] = {
4478 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4479 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4481 emit_move_insn (mask, array_to_constant (TImode, arr));
4482 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4487 (define_expand "vec_unpacku_lo_v8hi"
4488 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4491 (match_operand:V8HI 1 "spu_reg_operand" "r")
4492 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4495 rtx mask = gen_reg_rtx (TImode);
4496 unsigned char arr[16] = {
4497 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4498 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4500 emit_move_insn (mask, array_to_constant (TImode, arr));
4501 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4506 (define_expand "vec_unpacks_hi_v8hi"
4507 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4510 (match_operand:V8HI 1 "spu_reg_operand" "r")
4511 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4514 rtx tmp1 = gen_reg_rtx (V8HImode);
4515 rtx tmp2 = gen_reg_rtx (V4SImode);
4516 rtx mask = gen_reg_rtx (TImode);
4517 unsigned char arr[16] = {
4518 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4519 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4521 emit_move_insn (mask, array_to_constant (TImode, arr));
4522 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4523 emit_insn (gen_spu_xshw (tmp2, tmp1));
4524 emit_move_insn (operands[0], tmp2);
4529 (define_expand "vec_unpacks_lo_v8hi"
4530 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4533 (match_operand:V8HI 1 "spu_reg_operand" "r")
4534 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4537 rtx tmp1 = gen_reg_rtx (V8HImode);
4538 rtx tmp2 = gen_reg_rtx (V4SImode);
4539 rtx mask = gen_reg_rtx (TImode);
4540 unsigned char arr[16] = {
4541 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4542 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4544 emit_move_insn (mask, array_to_constant (TImode, arr));
4545 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4546 emit_insn (gen_spu_xshw (tmp2, tmp1));
4547 emit_move_insn (operands[0], tmp2);
4552 (define_expand "vec_unpacku_hi_v16qi"
4553 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4556 (match_operand:V16QI 1 "spu_reg_operand" "r")
4557 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4558 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4561 rtx mask = gen_reg_rtx (TImode);
4562 unsigned char arr[16] = {
4563 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4564 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4566 emit_move_insn (mask, array_to_constant (TImode, arr));
4567 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4572 (define_expand "vec_unpacku_lo_v16qi"
4573 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4576 (match_operand:V16QI 1 "spu_reg_operand" "r")
4577 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4578 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4581 rtx mask = gen_reg_rtx (TImode);
4582 unsigned char arr[16] = {
4583 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4584 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4586 emit_move_insn (mask, array_to_constant (TImode, arr));
4587 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4592 (define_expand "vec_unpacks_hi_v16qi"
4593 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4596 (match_operand:V16QI 1 "spu_reg_operand" "r")
4597 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4598 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4601 rtx tmp1 = gen_reg_rtx (V16QImode);
4602 rtx tmp2 = gen_reg_rtx (V8HImode);
4603 rtx mask = gen_reg_rtx (TImode);
4604 unsigned char arr[16] = {
4605 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4606 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4608 emit_move_insn (mask, array_to_constant (TImode, arr));
4609 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4610 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4611 emit_move_insn (operands[0], tmp2);
4616 (define_expand "vec_unpacks_lo_v16qi"
4617 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4620 (match_operand:V16QI 1 "spu_reg_operand" "r")
4621 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4622 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4625 rtx tmp1 = gen_reg_rtx (V16QImode);
4626 rtx tmp2 = gen_reg_rtx (V8HImode);
4627 rtx mask = gen_reg_rtx (TImode);
4628 unsigned char arr[16] = {
4629 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4630 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4632 emit_move_insn (mask, array_to_constant (TImode, arr));
4633 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4634 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4635 emit_move_insn (operands[0], tmp2);