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 2 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 this file; see the file COPYING. If not, write to the Free
15 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
18 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
21 ;; Define an insn type attribute. This is used in function unit delay
23 ;; multi0 is a multiple insn rtl whose first insn is in pipe0
24 ;; multi1 is a multiple insn rtl whose first insn is in pipe1
25 (define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
29 (define_attr "length" ""
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 behaviour of the double precision is that both pipes stall
59 ;; for 6 cycles and the 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 (eq_attr "type" "fpd")
63 "pipe0 + pipe1, fp, nothing*5")
65 (define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
68 (define_insn_reservation "STORE" 1 (eq_attr "type" "store")
71 (define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
74 (define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
77 (define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
78 "pipe1 + ls, nothing*5")
80 (define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
83 (define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
84 "pipe0+pipe1, nothing*3")
86 (define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
89 (define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
92 ;; Force pipe0 to occur before pipe 1 in a cycle.
93 (absence_set "pipe0" "pipe1")
102 (UNSPEC_EXTEND_CMP 5)
146 (UNSPEC_SPU_REALIGN_LOAD 49)
147 (UNSPEC_SPU_MASK_FOR_LOAD 50)
150 (include "predicates.md")
151 (include "constraints.md")
156 (define_mode_macro ALL [QI V16QI
164 ; Everything except DI and TI which are handled separately because
165 ; they need different constraints to correctly test VOIDmode constants
166 (define_mode_macro MOV [QI V16QI
173 (define_mode_macro DTI [DI TI])
175 (define_mode_macro VINT [QI V16QI
181 (define_mode_macro VQHSI [QI V16QI
185 (define_mode_macro VHSI [HI V8HI
188 (define_mode_macro VSDF [SF V4SF
191 (define_mode_macro VSI [SI V4SI])
192 (define_mode_macro VDI [DI V2DI])
193 (define_mode_macro VSF [SF V4SF])
194 (define_mode_macro VDF [DF V2DF])
196 (define_mode_attr bh [(QI "b") (V16QI "b")
200 (define_mode_attr d [(SF "") (V4SF "")
201 (DF "d") (V2DF "d")])
202 (define_mode_attr d6 [(SF "6") (V4SF "6")
203 (DF "d") (V2DF "d")])
204 (define_mode_attr f2i [(SF "SI") (V4SF "V4SI")
205 (DF "DI") (V2DF "V2DI")])
207 ;; Used for carry and borrow instructions.
208 (define_mode_macro CBOP [SI DI V4SI V2DI])
210 ;; Used in vec_set and vec_extract
211 (define_mode_macro V [V2DI V4SI V8HI V16QI V2DF V4SF])
212 (define_mode_attr inner [(V16QI "QI")
218 (define_mode_attr vmult [(V16QI "1")
224 (define_mode_attr voff [(V16QI "13")
234 (define_expand "mov<mode>"
235 [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
236 (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
239 if (spu_expand_mov(operands, <MODE>mode))
244 [(set (match_operand 0 "spu_reg_operand")
245 (match_operand 1 "immediate_operand"))]
249 (high (match_dup 1)))
251 (lo_sum (match_dup 0)
254 if (spu_split_immediate (operands))
260 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
261 (match_operand:SI 1 "immediate_operand" "s"))
266 ;; Whenever a function generates the 'pic' pattern above we need to
267 ;; load the pic_offset_table register.
268 ;; GCC doesn't deal well with labels in the middle of a block so we
269 ;; hardcode the offsets in the asm here.
270 (define_insn "load_pic_offset"
271 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
272 (unspec:SI [(const_int 0)] 0))
273 (set (match_operand:SI 1 "spu_reg_operand" "=r")
274 (unspec:SI [(const_int 0)] 0))]
276 "ila\t%1,.+8\;brsl\t%0,4"
277 [(set_attr "length" "8")
278 (set_attr "type" "multi0")])
283 (define_insn "_mov<mode>"
284 [(set (match_operand:MOV 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
285 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
286 "spu_valid_move (operands)"
294 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
297 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
298 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
303 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
304 (lo_sum:SI (match_operand:SI 1 "spu_reg_operand" "0")
305 (match_operand:SI 2 "immediate_operand" "i")))]
309 (define_insn "_movdi"
310 [(set (match_operand:DI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
311 (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
312 "spu_valid_move (operands)"
320 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
322 (define_insn "_movti"
323 [(set (match_operand:TI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
324 (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
325 "spu_valid_move (operands)"
333 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
335 (define_insn_and_split "load"
336 [(set (match_operand 0 "spu_reg_operand" "=r")
337 (match_operand 1 "memory_operand" "m"))
338 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
339 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))]
340 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
345 { spu_split_load(operands); DONE; })
347 (define_insn_and_split "store"
348 [(set (match_operand 0 "memory_operand" "=m")
349 (match_operand 1 "spu_reg_operand" "r"))
350 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
351 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
352 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
357 { spu_split_store(operands); DONE; })
359 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
361 (define_expand "cpat"
362 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
363 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
364 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
365 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
368 rtx x = gen_cpat_const (operands);
371 emit_move_insn (operands[0], x);
377 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
378 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
379 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
380 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
385 [(set_attr "type" "shuf")])
388 [(set (match_operand:TI 0 "spu_reg_operand")
389 (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
390 (match_operand:SI 2 "immediate_operand")
391 (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
393 [(set (match_dup:TI 0)
396 operands[4] = gen_cpat_const (operands);
403 (define_insn "extendqihi2"
404 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
405 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
409 (define_insn "extendhisi2"
410 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
411 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
415 (define_expand "extendsidi2"
416 [(set (match_dup:DI 2)
417 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
418 (set (match_operand:DI 0 "spu_reg_operand" "")
419 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
420 (parallel [(const_int 1)]))))]
423 operands[2] = gen_reg_rtx (DImode);
424 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
428 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
431 (match_operand:V2SI 1 "spu_reg_operand" "r")
432 (parallel [(const_int 1) ]))))]
436 (define_expand "extendqiti2"
437 [(set (match_operand:TI 0 "register_operand" "")
438 (sign_extend:TI (match_operand:QI 1 "register_operand" "")))]
440 "spu_expand_sign_extend(operands);
443 (define_expand "extendhiti2"
444 [(set (match_operand:TI 0 "register_operand" "")
445 (sign_extend:TI (match_operand:HI 1 "register_operand" "")))]
447 "spu_expand_sign_extend(operands);
450 (define_expand "extendsiti2"
451 [(set (match_operand:TI 0 "register_operand" "")
452 (sign_extend:TI (match_operand:SI 1 "register_operand" "")))]
454 "spu_expand_sign_extend(operands);
457 (define_expand "extendditi2"
458 [(set (match_operand:TI 0 "register_operand" "")
459 (sign_extend:TI (match_operand:DI 1 "register_operand" "")))]
461 "spu_expand_sign_extend(operands);
467 (define_insn "zero_extendqihi2"
468 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
469 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
471 "andi\t%0,%1,0x00ff")
473 (define_insn "zero_extendqisi2"
474 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
475 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
477 "andi\t%0,%1,0x00ff")
479 (define_expand "zero_extendhisi2"
480 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
481 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
482 (clobber (match_scratch:SI 2 "=&r"))]
485 rtx mask = gen_reg_rtx (SImode);
486 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
487 emit_move_insn (mask, GEN_INT (0xffff));
488 emit_insn (gen_andsi3(operands[0], op1, mask));
492 (define_insn "zero_extendsidi2"
493 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
494 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
497 [(set_attr "type" "shuf")])
499 (define_insn "zero_extendsiti2"
500 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
501 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
503 "rotqmbyi\t%0,%1,-12"
504 [(set_attr "type" "shuf")])
506 (define_insn "zero_extendditi2"
507 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
508 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
511 [(set_attr "type" "shuf")])
516 (define_insn "truncdiqi2"
517 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
518 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
521 [(set_attr "type" "shuf")])
523 (define_insn "truncdihi2"
524 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
525 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
528 [(set_attr "type" "shuf")])
530 (define_insn "truncdisi2"
531 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
532 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
535 [(set_attr "type" "shuf")])
537 (define_insn "trunctiqi2"
538 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
539 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
542 [(set_attr "type" "shuf")])
544 (define_insn "trunctihi2"
545 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
546 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
549 [(set_attr "type" "shuf")])
551 (define_insn "trunctisi2"
552 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
553 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
556 [(set_attr "type" "shuf")])
558 (define_insn "trunctidi2"
559 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
560 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
563 [(set_attr "type" "shuf")])
568 (define_insn "floatsisf2"
569 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
570 (float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
573 [(set_attr "type" "fp7")])
575 (define_insn "floatv4siv4sf2"
576 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
577 (float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
580 [(set_attr "type" "fp7")])
582 (define_insn "fix_truncsfsi2"
583 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
584 (fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
587 [(set_attr "type" "fp7")])
589 (define_insn "fix_truncv4sfv4si2"
590 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
591 (fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
594 [(set_attr "type" "fp7")])
596 (define_insn "floatunssisf2"
597 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
598 (unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
601 [(set_attr "type" "fp7")])
603 (define_insn "floatunsv4siv4sf2"
604 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
605 (unsigned_float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
608 [(set_attr "type" "fp7")])
610 (define_insn "fixuns_truncsfsi2"
611 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
612 (unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
615 [(set_attr "type" "fp7")])
617 (define_insn "fixuns_truncv4sfv4si2"
618 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
619 (unsigned_fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
622 [(set_attr "type" "fp7")])
624 (define_insn "extendsfdf2"
625 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
626 (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))]
629 [(set_attr "type" "fpd")])
631 (define_insn "truncdfsf2"
632 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
633 (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))]
636 [(set_attr "type" "fpd")])
638 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
639 (define_expand "floatsidf2"
640 [(set (match_operand:DF 0 "register_operand" "")
641 (float:DF (match_operand:SI 1 "register_operand" "")))]
645 rtx c0 = gen_reg_rtx (SImode);
646 rtx c1 = gen_reg_rtx (DFmode);
647 rtx r0 = gen_reg_rtx (SImode);
648 rtx r1 = gen_reg_rtx (DFmode);
650 emit_move_insn (c0, GEN_INT (-0x80000000ll));
651 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
653 emit_insn (gen_xorsi3 (r0, operands[1], c0));
657 emit_library_call_value (ufloat_optab->handlers[DFmode][SImode].libfunc,
658 NULL_RTX, LCT_NORMAL, DFmode, 1, r0, SImode);
659 insns = get_insns ();
661 emit_libcall_block (insns, r1, value,
662 gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
664 emit_insn (gen_subdf3 (operands[0], r1, c1));
668 (define_expand "floatdidf2"
669 [(set (match_operand:DF 0 "register_operand" "")
670 (float:DF (match_operand:DI 1 "register_operand" "")))]
674 rtx c0 = gen_reg_rtx (DImode);
675 rtx r0 = gen_reg_rtx (DImode);
676 rtx r1 = gen_reg_rtx (DFmode);
677 rtx r2 = gen_reg_rtx (DImode);
678 rtx setneg = gen_reg_rtx (DImode);
679 rtx isneg = gen_reg_rtx (SImode);
680 rtx neg = gen_reg_rtx (DImode);
681 rtx mask = gen_reg_rtx (DImode);
683 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
685 emit_insn (gen_negdi2 (neg, operands[1]));
686 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
687 emit_insn (gen_extend_compare (mask, isneg));
688 emit_insn (gen_selb (r0, neg, operands[1], mask));
689 emit_insn (gen_andc_di (setneg, c0, mask));
694 emit_library_call_value (ufloat_optab->handlers[DFmode][DImode].libfunc,
695 NULL_RTX, LCT_NORMAL, DFmode, 1, r0, DImode);
696 insns = get_insns ();
698 emit_libcall_block (insns, r1, value,
699 gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
701 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
702 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
708 (define_expand "addv16qi3"
709 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
710 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
711 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
714 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
715 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
716 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
717 rtx rhs_and = gen_reg_rtx (V8HImode);
718 rtx hi_char = gen_reg_rtx (V8HImode);
719 rtx lo_char = gen_reg_rtx (V8HImode);
720 rtx mask = gen_reg_rtx (V8HImode);
722 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
723 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
724 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
725 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
726 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
730 (define_insn "add<mode>3"
731 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
732 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
733 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
739 (define_expand "add<mode>3"
740 [(set (match_dup:VDI 3)
741 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
742 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
743 (set (match_dup:VDI 5)
744 (unspec:VDI [(match_dup 3)
746 (match_dup:TI 4)] UNSPEC_SHUFB))
747 (set (match_operand:VDI 0 "spu_reg_operand" "")
748 (unspec:VDI [(match_dup 1)
750 (match_dup 5)] UNSPEC_ADDX))]
753 unsigned char pat[16] = {
754 0x04, 0x05, 0x06, 0x07,
755 0x80, 0x80, 0x80, 0x80,
756 0x0c, 0x0d, 0x0e, 0x0f,
757 0x80, 0x80, 0x80, 0x80
759 operands[3] = gen_reg_rtx (<MODE>mode);
760 operands[4] = gen_reg_rtx (TImode);
761 operands[5] = gen_reg_rtx (<MODE>mode);
762 emit_move_insn (operands[4], array_to_constant (TImode, pat));
765 (define_insn "cg_<mode>"
766 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
767 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
768 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
772 (define_insn "cgx_<mode>"
773 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
774 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
775 (match_operand 2 "spu_reg_operand" "r")
776 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
780 (define_insn "addx_<mode>"
781 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
782 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
783 (match_operand 2 "spu_reg_operand" "r")
784 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
789 ;; This is not the most efficient implementation of addti3.
790 ;; We include this here because 1) the compiler needs it to be
791 ;; defined as the word size is 128-bit and 2) sometimes gcc
792 ;; substitutes an add for a constant left-shift. 2) is unlikely
793 ;; because we also give addti3 a high cost. In case gcc does
794 ;; generate TImode add, here is the code to do it.
795 ;; operand 2 is a nonmemory because the compiler requires it.
796 (define_insn "addti3"
797 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
798 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
799 (match_operand:TI 2 "spu_nonmem_operand" "r")))
800 (clobber (match_scratch:TI 3 "=&r"))]
809 [(set_attr "type" "multi0")
810 (set_attr "length" "28")])
812 (define_insn "add<mode>3"
813 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
814 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
815 (match_operand:VSF 2 "spu_reg_operand" "r")))]
818 [(set_attr "type" "fp6")])
820 (define_insn "add<mode>3"
821 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
822 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
823 (match_operand:VDF 2 "spu_reg_operand" "r")))]
826 [(set_attr "type" "fpd")])
831 (define_expand "subv16qi3"
832 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
833 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
834 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
837 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
838 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
839 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
840 rtx rhs_and = gen_reg_rtx (V8HImode);
841 rtx hi_char = gen_reg_rtx (V8HImode);
842 rtx lo_char = gen_reg_rtx (V8HImode);
843 rtx mask = gen_reg_rtx (V8HImode);
845 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
846 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
847 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
848 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
849 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
853 (define_insn "sub<mode>3"
854 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
855 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
856 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
862 (define_expand "sub<mode>3"
863 [(set (match_dup:VDI 3)
864 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
865 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
866 (set (match_dup:VDI 5)
867 (unspec:VDI [(match_dup 3)
869 (match_dup:TI 4)] UNSPEC_SHUFB))
870 (set (match_operand:VDI 0 "spu_reg_operand" "")
871 (unspec:VDI [(match_dup 1)
873 (match_dup 5)] UNSPEC_SFX))]
876 unsigned char pat[16] = {
877 0x04, 0x05, 0x06, 0x07,
878 0xc0, 0xc0, 0xc0, 0xc0,
879 0x0c, 0x0d, 0x0e, 0x0f,
880 0xc0, 0xc0, 0xc0, 0xc0
882 operands[3] = gen_reg_rtx (<MODE>mode);
883 operands[4] = gen_reg_rtx (TImode);
884 operands[5] = gen_reg_rtx (<MODE>mode);
885 emit_move_insn (operands[4], array_to_constant (TImode, pat));
888 (define_insn "bg_<mode>"
889 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
890 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
891 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
895 (define_insn "bgx_<mode>"
896 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
897 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
898 (match_operand 2 "spu_reg_operand" "r")
899 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
903 (define_insn "sfx_<mode>"
904 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
905 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
906 (match_operand 2 "spu_reg_operand" "r")
907 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
911 (define_insn "subti3"
912 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
913 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
914 (match_operand:TI 2 "spu_reg_operand" "r")))
915 (clobber (match_scratch:TI 3 "=&r"))
916 (clobber (match_scratch:TI 4 "=&r"))
917 (clobber (match_scratch:TI 5 "=&r"))]
928 [(set_attr "type" "multi0")
929 (set_attr "length" "36")])
931 (define_insn "sub<mode>3"
932 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
933 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
934 (match_operand:VSF 2 "spu_reg_operand" "r")))]
937 [(set_attr "type" "fp6")])
939 (define_insn "sub<mode>3"
940 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
941 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
942 (match_operand:VDF 2 "spu_reg_operand" "r")))]
945 [(set_attr "type" "fpd")])
950 (define_expand "negv16qi2"
951 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
952 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
955 rtx zero = gen_reg_rtx (V16QImode);
956 emit_move_insn (zero, CONST0_RTX (V16QImode));
957 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
961 (define_insn "neg<mode>2"
962 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
963 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
967 (define_expand "negdi2"
968 [(set (match_operand:DI 0 "spu_reg_operand" "")
969 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
972 rtx zero = gen_reg_rtx(DImode);
973 emit_move_insn(zero, GEN_INT(0));
974 emit_insn(gen_subdi3(operands[0], zero, operands[1]));
978 (define_expand "negti2"
979 [(set (match_operand:TI 0 "spu_reg_operand" "")
980 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
983 rtx zero = gen_reg_rtx(TImode);
984 emit_move_insn(zero, GEN_INT(0));
985 emit_insn(gen_subti3(operands[0], zero, operands[1]));
989 (define_expand "neg<mode>2"
991 [(set (match_operand:VSF 0 "spu_reg_operand" "")
992 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
993 (use (match_dup 2))])]
995 "operands[2] = gen_reg_rtx (<f2i>mode);
996 emit_move_insn (operands[2], spu_const (<f2i>mode, -0x80000000ull));")
998 (define_expand "neg<mode>2"
1000 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1001 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1002 (use (match_dup 2))])]
1004 "operands[2] = gen_reg_rtx (<f2i>mode);
1005 emit_move_insn (operands[2], spu_const (<f2i>mode, -0x8000000000000000ull));")
1007 (define_insn_and_split "_neg<mode>2"
1008 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1009 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1010 (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
1014 [(set (match_dup:<f2i> 3)
1015 (xor:<f2i> (match_dup:<f2i> 4)
1016 (match_dup:<f2i> 2)))]
1018 operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
1019 operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
1025 (define_expand "abs<mode>2"
1027 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1028 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1029 (use (match_dup 2))])]
1031 "operands[2] = gen_reg_rtx (<f2i>mode);
1032 emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffull));")
1034 (define_expand "abs<mode>2"
1036 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1037 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1038 (use (match_dup 2))])]
1040 "operands[2] = gen_reg_rtx (<f2i>mode);
1041 emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffffffffffull));")
1043 (define_insn_and_split "_abs<mode>2"
1044 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1045 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1046 (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
1050 [(set (match_dup:<f2i> 3)
1051 (and:<f2i> (match_dup:<f2i> 4)
1052 (match_dup:<f2i> 2)))]
1054 operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
1055 operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
1061 (define_insn "mulhi3"
1062 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1063 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1064 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1069 [(set_attr "type" "fp7")])
1071 (define_expand "mulv8hi3"
1072 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1073 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1074 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1077 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1078 rtx low = gen_reg_rtx (V4SImode);
1079 rtx high = gen_reg_rtx (V4SImode);
1080 rtx shift = gen_reg_rtx (V4SImode);
1081 rtx mask = gen_reg_rtx (V4SImode);
1083 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1084 emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1085 emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1086 emit_insn (gen_ashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1087 emit_insn (gen_selb (result, shift, low, mask));
1091 (define_expand "mul<mode>3"
1093 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1094 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1095 (match_operand:VSI 2 "spu_reg_operand" "")))
1096 (clobber (match_dup:VSI 3))
1097 (clobber (match_dup:VSI 4))
1098 (clobber (match_dup:VSI 5))
1099 (clobber (match_dup:VSI 6))])]
1102 operands[3] = gen_reg_rtx(<MODE>mode);
1103 operands[4] = gen_reg_rtx(<MODE>mode);
1104 operands[5] = gen_reg_rtx(<MODE>mode);
1105 operands[6] = gen_reg_rtx(<MODE>mode);
1108 (define_insn_and_split "_mulsi3"
1109 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1110 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1111 (match_operand:SI 2 "spu_arith_operand" "rK")))
1112 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1113 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1114 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1115 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1119 [(set (match_dup:SI 0)
1120 (mult:SI (match_dup:SI 1)
1123 HOST_WIDE_INT val = 0;
1124 rtx a = operands[3];
1125 rtx b = operands[4];
1126 rtx c = operands[5];
1127 rtx d = operands[6];
1128 if (GET_CODE(operands[2]) == CONST_INT)
1130 val = INTVAL(operands[2]);
1131 emit_move_insn(d, operands[2]);
1134 if (val && (val & 0xffff) == 0)
1136 emit_insn(gen_mpyh_si(operands[0], operands[2], operands[1]));
1138 else if (val > 0 && val < 0x10000)
1140 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1141 emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
1142 emit_insn(gen_mpyu_si(c, operands[1], cst));
1143 emit_insn(gen_addsi3(operands[0], a, c));
1147 emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
1148 emit_insn(gen_mpyh_si(b, operands[2], operands[1]));
1149 emit_insn(gen_mpyu_si(c, operands[1], operands[2]));
1150 emit_insn(gen_addsi3(d, a, b));
1151 emit_insn(gen_addsi3(operands[0], d, c));
1156 (define_insn_and_split "_mulv4si3"
1157 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1158 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1159 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1160 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1161 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1162 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1163 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1167 [(set (match_dup:V4SI 0)
1168 (mult:V4SI (match_dup:V4SI 1)
1169 (match_dup:V4SI 2)))]
1171 rtx a = operands[3];
1172 rtx b = operands[4];
1173 rtx c = operands[5];
1174 rtx d = operands[6];
1175 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1176 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1177 emit_insn(gen_spu_mpyh(a, op1, op2));
1178 emit_insn(gen_spu_mpyh(b, op2, op1));
1179 emit_insn(gen_spu_mpyu(c, op1, op2));
1180 emit_insn(gen_addv4si3(d, a, b));
1181 emit_insn(gen_addv4si3(operands[0], d, c));
1185 (define_insn "mulhisi3"
1186 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1187 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1188 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1191 [(set_attr "type" "fp7")])
1193 (define_insn "mulhisi3_imm"
1194 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1195 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1196 (match_operand:SI 2 "immediate_operand" "K")))]
1199 [(set_attr "type" "fp7")])
1201 (define_insn "umulhisi3"
1202 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1203 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1204 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1207 [(set_attr "type" "fp7")])
1209 (define_insn "umulhisi3_imm"
1210 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1211 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1212 (and:SI (match_operand:SI 2 "immediate_operand" "K") (const_int 65535))))]
1215 [(set_attr "type" "fp7")])
1217 (define_insn "mpyu_si"
1218 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1219 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1221 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1222 (const_int 65535))))]
1227 [(set_attr "type" "fp7")])
1229 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1230 ;; It's faster to do the multiplies in parallel then add them. If we
1231 ;; merge a multiply and add it prevents the multiplies from happening in
1233 (define_insn "mpya_si"
1234 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1235 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1236 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1237 (match_operand:SI 3 "spu_reg_operand" "r")))]
1240 [(set_attr "type" "fp7")])
1242 (define_insn "mpyh_si"
1243 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1244 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1246 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1247 (const_int 65535))))]
1250 [(set_attr "type" "fp7")])
1252 (define_insn "mpys_si"
1253 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1255 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1256 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1260 [(set_attr "type" "fp7")])
1262 (define_insn "mpyhh_si"
1263 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1264 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1266 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1270 [(set_attr "type" "fp7")])
1272 (define_insn "mpyhhu_si"
1273 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1274 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1276 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1280 [(set_attr "type" "fp7")])
1282 (define_insn "mpyhha_si"
1283 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1284 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1286 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1288 (match_operand:SI 3 "spu_reg_operand" "0")))]
1291 [(set_attr "type" "fp7")])
1293 (define_insn "mul<mode>3"
1294 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1295 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1296 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1299 [(set_attr "type" "fp<d6>")])
1301 (define_insn "fma_<mode>"
1302 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1303 (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1304 (match_operand:VSF 2 "spu_reg_operand" "r"))
1305 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1308 [(set_attr "type" "fp6")])
1310 (define_insn "fnms_<mode>"
1311 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1312 (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1313 (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1314 (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1317 [(set_attr "type" "fp6")])
1319 (define_insn "fms_<mode>"
1320 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1321 (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1322 (match_operand:VSF 2 "spu_reg_operand" "r"))
1323 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1326 [(set_attr "type" "fp6")])
1328 (define_insn "fma_<mode>"
1329 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1330 (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1331 (match_operand:VDF 2 "spu_reg_operand" "r"))
1332 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1335 [(set_attr "type" "fpd")])
1337 (define_insn "fnma_<mode>"
1338 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1339 (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1340 (match_operand:VDF 2 "spu_reg_operand" "r"))
1341 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1344 [(set_attr "type" "fpd")])
1346 (define_insn "fnms_<mode>"
1347 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1348 (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1349 (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1350 (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1353 [(set_attr "type" "fpd")])
1355 (define_insn "fms_<mode>"
1356 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1357 (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1358 (match_operand:VDF 2 "spu_reg_operand" "r"))
1359 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1362 [(set_attr "type" "fpd")])
1365 ;; mul highpart, used for divide by constant optimizations.
1367 (define_expand "smulsi3_highpart"
1368 [(set (match_operand:SI 0 "register_operand" "")
1371 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1372 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1376 rtx t0 = gen_reg_rtx (SImode);
1377 rtx t1 = gen_reg_rtx (SImode);
1378 rtx t2 = gen_reg_rtx (SImode);
1379 rtx t3 = gen_reg_rtx (SImode);
1380 rtx t4 = gen_reg_rtx (SImode);
1381 rtx t5 = gen_reg_rtx (SImode);
1382 rtx t6 = gen_reg_rtx (SImode);
1383 rtx t7 = gen_reg_rtx (SImode);
1384 rtx t8 = gen_reg_rtx (SImode);
1385 rtx t9 = gen_reg_rtx (SImode);
1386 rtx t11 = gen_reg_rtx (SImode);
1387 rtx t12 = gen_reg_rtx (SImode);
1388 rtx t14 = gen_reg_rtx (SImode);
1389 rtx t15 = gen_reg_rtx (HImode);
1390 rtx t16 = gen_reg_rtx (HImode);
1391 rtx t17 = gen_reg_rtx (HImode);
1392 rtx t18 = gen_reg_rtx (HImode);
1393 rtx t19 = gen_reg_rtx (SImode);
1394 rtx t20 = gen_reg_rtx (SImode);
1395 rtx t21 = gen_reg_rtx (SImode);
1396 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1397 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1398 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1399 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1401 emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1402 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1403 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1404 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1405 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1406 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1407 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1408 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1410 /* Gen carry bits (in t9 and t11). */
1411 emit_insn (gen_addsi3 (t8, t2, t3));
1412 emit_insn (gen_cg_si (t9, t2, t3));
1413 emit_insn (gen_cg_si (t11, t8, t4));
1415 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1416 emit_insn (gen_addx_si (t12, t5, t6, t9));
1417 emit_insn (gen_addx_si (t14, t12, t7, t11));
1419 /* mpys treats both operands as signed when we really want it to treat
1420 the first operand as signed and the second operand as unsigned.
1421 The code below corrects for that difference. */
1422 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1423 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1424 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1425 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1426 emit_insn (gen_extendhisi2 (t19, t17));
1427 emit_insn (gen_extendhisi2 (t20, t18));
1428 emit_insn (gen_addsi3 (t21, t19, t20));
1429 emit_insn (gen_addsi3 (operands[0], t14, t21));
1433 (define_expand "umulsi3_highpart"
1434 [(set (match_operand:SI 0 "register_operand" "")
1437 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1438 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1443 rtx t0 = gen_reg_rtx (SImode);
1444 rtx t1 = gen_reg_rtx (SImode);
1445 rtx t2 = gen_reg_rtx (SImode);
1446 rtx t3 = gen_reg_rtx (SImode);
1447 rtx t4 = gen_reg_rtx (SImode);
1448 rtx t5 = gen_reg_rtx (SImode);
1449 rtx t6 = gen_reg_rtx (SImode);
1450 rtx t7 = gen_reg_rtx (SImode);
1451 rtx t8 = gen_reg_rtx (SImode);
1452 rtx t9 = gen_reg_rtx (SImode);
1453 rtx t10 = gen_reg_rtx (SImode);
1454 rtx t12 = gen_reg_rtx (SImode);
1455 rtx t13 = gen_reg_rtx (SImode);
1456 rtx t14 = gen_reg_rtx (SImode);
1457 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1458 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1459 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1461 emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1462 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1463 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1464 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1465 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1466 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1467 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1468 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1469 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1471 /* Gen carry bits (in t10 and t12). */
1472 emit_insn (gen_addsi3 (t9, t1, t5));
1473 emit_insn (gen_cg_si (t10, t1, t5));
1474 emit_insn (gen_cg_si (t12, t9, t6));
1476 /* Gen high 32 bits in operand[0]. */
1477 emit_insn (gen_addx_si (t13, t4, t7, t10));
1478 emit_insn (gen_addx_si (t14, t13, t8, t12));
1479 emit_insn (gen_movsi (operands[0], t14));
1486 ;; Not necessarily the best implementation of divide but faster then
1487 ;; the default that gcc provides because this is inlined and it uses
1489 (define_insn "divmodsi4"
1490 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1491 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1492 (match_operand:SI 2 "spu_reg_operand" "r")))
1493 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1494 (mod:SI (match_dup 1)
1496 (clobber (match_scratch:SI 4 "=&r"))
1497 (clobber (match_scratch:SI 5 "=&r"))
1498 (clobber (match_scratch:SI 6 "=&r"))
1499 (clobber (match_scratch:SI 7 "=&r"))
1500 (clobber (match_scratch:SI 8 "=&r"))
1501 (clobber (match_scratch:SI 9 "=&r"))
1502 (clobber (match_scratch:SI 10 "=&r"))
1503 (clobber (match_scratch:SI 11 "=&r"))
1504 (clobber (match_scratch:SI 12 "=&r"))
1505 (clobber (reg:SI 130))]
1513 selb %8,%8,%1,%10\\n\\
1514 selb %9,%9,%2,%11\\n\\
1520 shlqbyi %3,%8,0\\n\\
1521 xor %11,%10,%11\\n\\
1525 1: or %12,%0,%5\\n\\
1526 rotqmbii %5,%5,-1\\n\\
1530 rotqmbii %4,%4,-1\\n\\
1531 selb %0,%12,%0,%6\\n\\
1533 selb %3,%7,%3,%6\\n\\
1537 selb %3,%8,%3,%10\\n\\
1539 [(set_attr "type" "multi0")
1540 (set_attr "length" "128")])
1542 (define_insn "udivmodsi4"
1543 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1544 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1545 (match_operand:SI 2 "spu_reg_operand" "r")))
1546 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1547 (umod:SI (match_dup 1)
1549 (clobber (match_scratch:SI 4 "=&r"))
1550 (clobber (match_scratch:SI 5 "=&r"))
1551 (clobber (match_scratch:SI 6 "=&r"))
1552 (clobber (match_scratch:SI 7 "=&r"))
1553 (clobber (match_scratch:SI 8 "=&r"))
1554 (clobber (reg:SI 130))]
1567 rotqmbii %5,%5,-1\\n\\
1571 rotqmbii %4,%4,-1\\n\\
1572 selb %0,%8,%0,%6\\n\\
1574 selb %3,%7,%3,%6\\n\\
1577 [(set_attr "type" "multi0")
1578 (set_attr "length" "80")])
1580 (define_insn_and_split "div<mode>3"
1581 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1582 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1583 (match_operand:VSF 2 "spu_reg_operand" "r")))
1584 (clobber (match_scratch:VSF 3 "=&r"))
1585 (clobber (match_scratch:VSF 4 "=&r"))]
1589 [(set (match_dup:VSF 0)
1590 (div:VSF (match_dup:VSF 1)
1592 (clobber (match_dup:VSF 3))
1593 (clobber (match_dup:VSF 4))]
1595 emit_insn(gen_frest_<mode>(operands[3], operands[2]));
1596 emit_insn(gen_fi_<mode>(operands[3], operands[2], operands[3]));
1597 emit_insn(gen_mul<mode>3(operands[4], operands[1], operands[3]));
1598 emit_insn(gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
1599 emit_insn(gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
1606 (define_insn_and_split "sqrtsf2"
1607 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1608 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1609 (clobber (match_scratch:SF 2 "=&r"))
1610 (clobber (match_scratch:SF 3 "=&r"))
1611 (clobber (match_scratch:SF 4 "=&r"))
1612 (clobber (match_scratch:SF 5 "=&r"))]
1616 [(set (match_dup:SF 0)
1617 (sqrt:SF (match_dup:SF 1)))
1618 (clobber (match_dup:SF 2))
1619 (clobber (match_dup:SF 3))
1620 (clobber (match_dup:SF 4))
1621 (clobber (match_dup:SF 5))]
1623 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1624 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1625 emit_insn(gen_frsqest_sf(operands[2],operands[1]));
1626 emit_insn(gen_fi_sf(operands[2],operands[1],operands[2]));
1627 emit_insn(gen_mulsf3(operands[5],operands[2],operands[1]));
1628 emit_insn(gen_mulsf3(operands[3],operands[5],operands[3]));
1629 emit_insn(gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1630 emit_insn(gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1634 (define_insn "frest_<mode>"
1635 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1636 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1639 [(set_attr "type" "shuf")])
1641 (define_insn "frsqest_<mode>"
1642 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1643 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1646 [(set_attr "type" "shuf")])
1648 (define_insn "fi_<mode>"
1649 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1650 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1651 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1654 [(set_attr "type" "fp7")])
1659 (define_insn "and<mode>3"
1660 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1661 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1662 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1666 and%j2i\t%0,%1,%J2")
1668 (define_insn "anddi3"
1669 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1670 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1671 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1675 and%k2i\t%0,%1,%K2")
1677 (define_insn "andti3"
1678 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1679 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1680 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1684 and%m2i\t%0,%1,%L2")
1686 (define_insn "andc_<mode>"
1687 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1688 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1689 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1693 (define_insn "nand_<mode>"
1694 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1695 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1696 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1703 (define_insn "ior<mode>3"
1704 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1705 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
1706 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
1713 (define_insn "iordi3"
1714 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
1715 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
1716 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
1723 (define_insn "iorti3"
1724 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
1725 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
1726 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
1733 (define_insn "orc_<mode>"
1734 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1735 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1736 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1740 (define_insn "nor_<mode>"
1741 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1742 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1743 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1749 (define_insn "xor<mode>3"
1750 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1751 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1752 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
1756 xor%j2i\t%0,%1,%S2")
1758 (define_insn "xordi3"
1759 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1760 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1761 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1765 xor%k2i\t%0,%1,%K2")
1767 (define_insn "xorti3"
1768 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1769 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1770 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1774 xor%m2i\t%0,%1,%L2")
1776 (define_insn "eqv_<mode>"
1777 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1778 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1779 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1785 (define_insn "one_cmpl<mode>2"
1786 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1787 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
1794 (define_expand "selb"
1795 [(set (match_operand 0 "spu_reg_operand" "")
1796 (unspec [(match_operand 1 "spu_reg_operand" "")
1797 (match_operand 2 "spu_reg_operand" "")
1798 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
1801 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
1802 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
1807 ;; This could be defined as a combination of logical operations, but at
1808 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
1809 (define_insn "_selb"
1810 [(set (match_operand 0 "spu_reg_operand" "=r")
1811 (unspec [(match_operand 1 "spu_reg_operand" "r")
1812 (match_operand 2 "spu_reg_operand" "r")
1813 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
1814 "GET_MODE(operands[0]) == GET_MODE(operands[1])
1815 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
1816 "selb\t%0,%1,%2,%3")
1819 ;; Misc. byte/bit operations
1820 ;; clz/ctz/ffs/popcount/parity
1823 (define_insn "clz<mode>2"
1824 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
1825 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
1829 (define_expand "ctz<mode>2"
1831 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
1832 (set (match_dup 3) (and:VSI (match_dup 1)
1834 (set (match_dup 4) (clz:VSI (match_dup 3)))
1835 (set (match_operand:VSI 0 "spu_reg_operand" "")
1836 (minus:VSI (match_dup 5) (match_dup 4)))]
1839 operands[2] = gen_reg_rtx (<MODE>mode);
1840 operands[3] = gen_reg_rtx (<MODE>mode);
1841 operands[4] = gen_reg_rtx (<MODE>mode);
1842 operands[5] = spu_const(<MODE>mode, 31);
1845 (define_expand "ffs<mode>2"
1847 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
1848 (set (match_dup 3) (and:VSI (match_dup 1)
1850 (set (match_dup 4) (clz:VSI (match_dup 3)))
1851 (set (match_operand:VSI 0 "spu_reg_operand" "")
1852 (minus:VSI (match_dup 5) (match_dup 4)))]
1855 operands[2] = gen_reg_rtx (<MODE>mode);
1856 operands[3] = gen_reg_rtx (<MODE>mode);
1857 operands[4] = gen_reg_rtx (<MODE>mode);
1858 operands[5] = spu_const(<MODE>mode, 32);
1861 (define_expand "popcountsi2"
1863 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
1866 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
1867 (set (match_operand:SI 0 "spu_reg_operand" "")
1868 (sign_extend:SI (match_dup 3)))]
1871 operands[2] = gen_reg_rtx (SImode);
1872 operands[3] = gen_reg_rtx (HImode);
1875 (define_expand "paritysi2"
1876 [(set (match_operand:SI 0 "spu_reg_operand" "")
1877 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
1880 operands[2] = gen_reg_rtx (SImode);
1881 emit_insn (gen_popcountsi2(operands[2], operands[1]));
1882 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
1886 (define_insn "cntb_si"
1887 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1888 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
1892 [(set_attr "type" "fxb")])
1894 (define_insn "cntb_v16qi"
1895 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1896 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
1900 [(set_attr "type" "fxb")])
1902 (define_insn "sumb_si"
1903 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
1904 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
1907 [(set_attr "type" "fxb")])
1912 (define_insn "ashl<mode>3"
1913 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1914 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1915 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
1920 [(set_attr "type" "fx3")])
1922 (define_insn_and_split "ashldi3"
1923 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1924 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1925 (match_operand:SI 2 "spu_shift_operand" "r,I")))
1926 (clobber (match_scratch:SI 3 "=&r,X"))]
1930 [(set (match_dup:DI 0)
1931 (ashift:DI (match_dup:DI 1)
1934 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
1935 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
1936 rtx op2 = operands[2];
1937 rtx op3 = operands[3];
1939 if (GET_CODE (operands[2]) == REG)
1941 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
1942 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
1943 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
1944 emit_insn (gen_shlqbi_ti (op0, op0, op3));
1948 HOST_WIDE_INT val = INTVAL (operands[2]);
1949 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
1950 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
1952 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
1957 (define_expand "ashlti3"
1958 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
1959 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
1960 (match_operand:SI 2 "spu_nonmem_operand" "")))
1961 (clobber (match_dup:TI 3))])]
1963 "if (GET_CODE (operands[2]) == CONST_INT)
1965 emit_insn(gen_ashlti3_imm(operands[0], operands[1], operands[2]));
1968 operands[3] = gen_reg_rtx (TImode);")
1970 (define_insn_and_split "ashlti3_imm"
1971 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1972 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1973 (match_operand:SI 2 "immediate_operand" "O,P")))]
1978 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
1979 [(set (match_dup:TI 0)
1980 (ashift:TI (match_dup:TI 1)
1982 (set (match_dup:TI 0)
1983 (ashift:TI (match_dup:TI 0)
1986 HOST_WIDE_INT val = INTVAL(operands[2]);
1987 operands[3] = GEN_INT (val&7);
1988 operands[4] = GEN_INT (val&0x78);
1990 [(set_attr "type" "shuf,shuf")])
1992 (define_insn_and_split "ashlti3_reg"
1993 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1994 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
1995 (match_operand:SI 2 "spu_reg_operand" "r")))
1996 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2000 [(set (match_dup:TI 3)
2001 (ashift:TI (match_dup:TI 1)
2002 (and:SI (match_dup:SI 2)
2004 (set (match_dup:TI 0)
2005 (ashift:TI (match_dup:TI 3)
2006 (and:SI (match_dup:SI 2)
2010 (define_insn "shlqbybi_ti"
2011 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2012 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2013 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2018 shlqbyi\t%0,%1,%2/8"
2019 [(set_attr "type" "shuf,shuf")])
2021 (define_insn "shlqbi_ti"
2022 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2023 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2024 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2030 [(set_attr "type" "shuf,shuf")])
2032 (define_insn "shlqby_ti"
2033 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2034 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2035 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2041 [(set_attr "type" "shuf,shuf")])
2046 (define_insn_and_split "lshr<mode>3"
2047 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2048 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2049 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
2050 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2054 rot<bh>mi\t%0,%1,%N2"
2055 "reload_completed && GET_CODE (operands[2]) == REG"
2056 [(set (match_dup:VHSI 3)
2057 (neg:VHSI (match_dup:VHSI 2)))
2058 (set (match_dup:VHSI 0)
2059 (lshiftrt:VHSI (match_dup:VHSI 1)
2060 (neg:VHSI (match_dup:VHSI 3))))]
2062 [(set_attr "type" "*,fx3")])
2065 (define_insn "rotm_<mode>"
2066 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2067 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2068 (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
2072 rot<bh>mi\t%0,%1,%2"
2073 [(set_attr "type" "fx3")])
2075 (define_expand "lshr<mode>3"
2076 [(parallel [(set (match_operand:DTI 0 "spu_reg_operand" "")
2077 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "")
2078 (match_operand:SI 2 "spu_nonmem_operand" "")))
2079 (clobber (match_dup:DTI 3))
2080 (clobber (match_dup:SI 4))
2081 (clobber (match_dup:SI 5))])]
2083 "if (GET_CODE (operands[2]) == CONST_INT)
2085 emit_insn(gen_lshr<mode>3_imm(operands[0], operands[1], operands[2]));
2088 operands[3] = gen_reg_rtx (<MODE>mode);
2089 operands[4] = gen_reg_rtx (SImode);
2090 operands[5] = gen_reg_rtx (SImode);")
2092 (define_insn_and_split "lshr<mode>3_imm"
2093 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2094 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2095 (match_operand:SI 2 "immediate_operand" "O,P")))]
2098 rotqmbyi\t%0,%1,%N2/8
2099 rotqmbii\t%0,%1,%N2"
2100 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2101 [(set (match_dup:DTI 0)
2102 (lshiftrt:DTI (match_dup:DTI 1)
2104 (set (match_dup:DTI 0)
2105 (lshiftrt:DTI (match_dup:DTI 0)
2108 HOST_WIDE_INT val = INTVAL(operands[2]);
2109 operands[4] = GEN_INT (val&7);
2110 operands[5] = GEN_INT (val&0x78);
2112 [(set_attr "type" "shuf,shuf")])
2114 (define_insn_and_split "lshr<mode>3_reg"
2115 [(set (match_operand:DTI 0 "spu_reg_operand" "=r")
2116 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r")
2117 (match_operand:SI 2 "spu_reg_operand" "r")))
2118 (clobber (match_operand:DTI 3 "spu_reg_operand" "=&r"))
2119 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
2120 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))]
2124 [(set (match_dup:DTI 3)
2125 (lshiftrt:DTI (match_dup:DTI 1)
2126 (and:SI (neg:SI (match_dup:SI 4))
2128 (set (match_dup:DTI 0)
2129 (lshiftrt:DTI (match_dup:DTI 3)
2130 (and:SI (neg:SI (match_dup:SI 5))
2133 emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2]));
2134 emit_insn(gen_subsi3(operands[5], GEN_INT(7), operands[2]));
2137 (define_insn "rotqmbybi_<mode>"
2138 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2139 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2140 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2145 rotqmbyi\t%0,%1,%2/8"
2146 [(set_attr "type" "shuf")])
2148 (define_insn "rotqmbi_<mode>"
2149 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2150 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2151 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2157 [(set_attr "type" "shuf")])
2159 (define_insn "rotqmby_<mode>"
2160 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2161 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2162 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2168 [(set_attr "type" "shuf")])
2173 (define_insn_and_split "ashr<mode>3"
2174 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2175 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2176 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
2177 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2181 rotma<bh>i\t%0,%1,%N2"
2182 "reload_completed && GET_CODE (operands[2]) == REG"
2183 [(set (match_dup:VHSI 3)
2184 (neg:VHSI (match_dup:VHSI 2)))
2185 (set (match_dup:VHSI 0)
2186 (ashiftrt:VHSI (match_dup:VHSI 1)
2187 (neg:VHSI (match_dup:VHSI 3))))]
2189 [(set_attr "type" "*,fx3")])
2192 (define_insn "rotma_<mode>"
2193 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2194 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2195 (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
2199 rotma<bh>i\t%0,%1,%2"
2200 [(set_attr "type" "fx3")])
2202 (define_insn_and_split "ashrdi3"
2203 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2204 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2205 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2206 (clobber (match_scratch:TI 3 "=&r,&r"))
2207 (clobber (match_scratch:TI 4 "=&r,&r"))
2208 (clobber (match_scratch:SI 5 "=&r,&r"))]
2212 [(set (match_dup:DI 0)
2213 (ashiftrt:DI (match_dup:DI 1)
2216 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2217 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2218 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2219 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2220 rtx op2 = operands[2];
2221 rtx op3 = operands[3];
2222 rtx op4 = operands[4];
2223 rtx op5 = operands[5];
2225 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2227 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2228 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2229 emit_insn (gen_spu_fsm (op0v, op0s));
2231 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2233 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2234 HOST_WIDE_INT val = INTVAL (op2);
2235 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2236 emit_insn (gen_spu_xswd (op0d, op0v));
2238 emit_insn (gen_ashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2242 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2243 unsigned char arr[16] = {
2244 0xff, 0xff, 0xff, 0xff,
2245 0xff, 0xff, 0xff, 0xff,
2246 0x00, 0x00, 0x00, 0x00,
2247 0x00, 0x00, 0x00, 0x00
2250 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2251 emit_move_insn (op4, array_to_constant (TImode, arr));
2252 emit_insn (gen_spu_fsm (op3v, op5));
2254 if (GET_CODE (operands[2]) == REG)
2256 emit_insn (gen_selb (op4, op3, op1, op4));
2257 emit_insn (gen_negsi2 (op5, op2));
2258 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2259 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2263 HOST_WIDE_INT val = -INTVAL (op2);
2264 emit_insn (gen_selb (op0, op3, op1, op4));
2266 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2268 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2275 (define_expand "ashrti3"
2276 [(set (match_operand:TI 0 "spu_reg_operand" "")
2277 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "")
2278 (match_operand:SI 2 "spu_nonmem_operand" "")))]
2281 rtx sign_shift = gen_reg_rtx (SImode);
2282 rtx sign_mask = gen_reg_rtx (TImode);
2283 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2284 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2285 rtx t = gen_reg_rtx (TImode);
2286 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2287 emit_insn (gen_ashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2288 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2289 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2290 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2291 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2295 ;; fsm is used after rotam to replicate the sign across the whole register.
2296 (define_insn "fsm_ti"
2297 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2298 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2301 [(set_attr "type" "shuf")])
2306 (define_insn "rotl<mode>3"
2307 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2308 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2309 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
2314 [(set_attr "type" "fx3")])
2316 (define_insn "rotlti3"
2317 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2318 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2319 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2322 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2325 rotqbyi\t%0,%1,%2/8\;rotqbii\t%0,%0,%2%%8"
2326 [(set_attr "length" "8,4,4,8")
2327 (set_attr "type" "multi1,shuf,shuf,multi1")])
2329 (define_insn "rotqbybi_ti"
2330 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2331 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2332 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2337 rotqbyi\t%0,%1,%2/8"
2338 [(set_attr "type" "shuf,shuf")])
2340 (define_insn "rotqby_ti"
2341 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2342 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2343 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2349 [(set_attr "type" "shuf,shuf")])
2351 (define_insn "rotqbi_ti"
2352 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2353 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2354 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2359 rotqbii\t%0,%1,%2%%8"
2360 [(set_attr "type" "shuf,shuf")])
2363 ;; struct extract/insert
2364 ;; We have to handle mem's because GCC will generate invalid SUBREG's
2365 ;; if it handles them. We generate better code anyway.
2367 (define_expand "extv"
2368 [(set (match_operand 0 "register_operand" "")
2369 (sign_extract (match_operand 1 "register_operand" "")
2370 (match_operand:SI 2 "const_int_operand" "")
2371 (match_operand:SI 3 "const_int_operand" "")))]
2373 { spu_expand_extv(operands, 0); DONE; })
2375 (define_expand "extzv"
2376 [(set (match_operand 0 "register_operand" "")
2377 (zero_extract (match_operand 1 "register_operand" "")
2378 (match_operand:SI 2 "const_int_operand" "")
2379 (match_operand:SI 3 "const_int_operand" "")))]
2381 { spu_expand_extv(operands, 1); DONE; })
2383 (define_expand "insv"
2384 [(set (zero_extract (match_operand 0 "register_operand" "")
2385 (match_operand:SI 1 "const_int_operand" "")
2386 (match_operand:SI 2 "const_int_operand" ""))
2387 (match_operand 3 "nonmemory_operand" ""))]
2389 { spu_expand_insv(operands); DONE; })
2392 ;; String/block move insn.
2393 ;; Argument 0 is the destination
2394 ;; Argument 1 is the source
2395 ;; Argument 2 is the length
2396 ;; Argument 3 is the alignment
2398 (define_expand "movstrsi"
2399 [(parallel [(set (match_operand:BLK 0 "" "")
2400 (match_operand:BLK 1 "" ""))
2401 (use (match_operand:SI 2 "" ""))
2402 (use (match_operand:SI 3 "" ""))])]
2406 if (spu_expand_block_move (operands))
2415 (define_insn "indirect_jump"
2416 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2419 [(set_attr "type" "br")])
2423 (label_ref (match_operand 0 "" "")))]
2426 [(set_attr "type" "br")])
2431 ;; This will be used for leaf functions, that don't save any regs and
2432 ;; don't have locals on stack, maybe... that is for functions that
2433 ;; don't change $sp and don't need to save $lr.
2434 (define_expand "return"
2439 ;; used in spu_expand_epilogue to generate return from a function and
2440 ;; explicitly set use of $lr.
2442 (define_insn "_return"
2446 [(set_attr "type" "br")])
2452 (define_insn "ceq_<mode>"
2453 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2454 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2455 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2459 ceq<bh>i\t%0,%1,%2")
2461 (define_insn_and_split "ceq_di"
2462 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2463 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2464 (match_operand:DI 2 "spu_reg_operand" "r")))]
2468 [(set (match_dup:SI 0)
2469 (eq:SI (match_dup:DI 1)
2472 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2473 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2474 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2475 emit_insn (gen_ceq_v4si (op0, op1, op2));
2476 emit_insn (gen_spu_gb (op0, op0));
2477 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2482 ;; We provide the TI compares for completeness and because some parts of
2483 ;; gcc/libgcc use them, even though user code might never see it.
2484 (define_insn "ceq_ti"
2485 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2486 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2487 (match_operand:TI 2 "spu_reg_operand" "r")))]
2489 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2490 [(set_attr "type" "multi0")
2491 (set_attr "length" "12")])
2493 (define_insn "ceq_<mode>"
2494 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2495 (eq:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
2496 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2500 (define_insn "cmeq_<mode>"
2501 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2502 (eq:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2503 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2507 (define_insn "ceq_vec"
2508 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2509 (eq:SI (match_operand 1 "spu_reg_operand" "r")
2510 (match_operand 2 "spu_reg_operand" "r")))]
2511 "VECTOR_MODE_P(GET_MODE(operands[1]))
2512 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2513 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2514 [(set_attr "length" "12")])
2519 (define_insn "cgt_<mode>"
2520 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2521 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2522 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2526 cgt<bh>i\t%0,%1,%2")
2528 (define_insn "cgt_di_m1"
2529 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2530 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2535 (define_insn_and_split "cgt_di"
2536 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2537 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2538 (match_operand:DI 2 "spu_reg_operand" "r")))
2539 (clobber (match_scratch:V4SI 3 "=&r"))
2540 (clobber (match_scratch:V4SI 4 "=&r"))
2541 (clobber (match_scratch:V4SI 5 "=&r"))]
2545 [(set (match_dup:SI 0)
2546 (gt:SI (match_dup:DI 1)
2549 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2550 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2551 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2552 rtx op3 = operands[3];
2553 rtx op4 = operands[4];
2554 rtx op5 = operands[5];
2555 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
2556 emit_insn (gen_clgt_v4si (op3, op1, op2));
2557 emit_insn (gen_ceq_v4si (op4, op1, op2));
2558 emit_insn (gen_cgt_v4si (op5, op1, op2));
2559 emit_insn (gen_spu_xswd (op3d, op3));
2560 emit_insn (gen_selb (op0, op5, op3, op4));
2564 (define_insn "cgt_ti"
2565 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2566 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
2567 (match_operand:TI 2 "spu_reg_operand" "r")))
2568 (clobber (match_scratch:V4SI 3 "=&r"))
2569 (clobber (match_scratch:V4SI 4 "=&r"))
2570 (clobber (match_scratch:V4SI 5 "=&r"))]
2576 selb\t%0,%4,%0,%3\;\
2578 selb\t%0,%4,%0,%3\;\
2581 [(set_attr "type" "multi0")
2582 (set_attr "length" "36")])
2584 (define_insn "cgt_<mode>"
2585 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2586 (gt:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
2587 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2591 (define_insn "cmgt_<mode>"
2592 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2593 (gt:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2594 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2601 (define_insn "clgt_<mode>"
2602 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2603 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2604 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2608 clgt<bh>i\t%0,%1,%2")
2610 (define_insn_and_split "clgt_di"
2611 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2612 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
2613 (match_operand:DI 2 "spu_reg_operand" "r")))
2614 (clobber (match_scratch:V4SI 3 "=&r"))
2615 (clobber (match_scratch:V4SI 4 "=&r"))
2616 (clobber (match_scratch:V4SI 5 "=&r"))]
2620 [(set (match_dup:SI 0)
2621 (gtu:SI (match_dup:DI 1)
2624 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2625 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2626 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2627 rtx op3 = operands[3];
2628 rtx op4 = operands[4];
2629 rtx op5 = operands[5];
2630 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
2631 emit_insn (gen_clgt_v4si (op3, op1, op2));
2632 emit_insn (gen_ceq_v4si (op4, op1, op2));
2633 emit_insn (gen_spu_xswd (op5d, op3));
2634 emit_insn (gen_selb (op0, op3, op5, op4));
2638 (define_insn "clgt_ti"
2639 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2640 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
2641 (match_operand:TI 2 "spu_reg_operand" "r")))
2642 (clobber (match_scratch:V4SI 3 "=&r"))
2643 (clobber (match_scratch:V4SI 4 "=&r"))]
2648 selb\t%0,%4,%0,%3\;\
2650 selb\t%0,%4,%0,%3\;\
2653 [(set_attr "type" "multi0")
2654 (set_attr "length" "32")])
2661 (if_then_else (match_operator 1 "branch_comparison_operator"
2663 "spu_reg_operand" "r")
2665 (label_ref (match_operand 0 "" ""))
2669 [(set_attr "type" "br")])
2673 (if_then_else (match_operator 0 "branch_comparison_operator"
2675 "spu_reg_operand" "r")
2681 [(set_attr "type" "br")])
2685 (if_then_else (match_operator 1 "branch_comparison_operator"
2687 "spu_reg_operand" "r")
2690 (label_ref (match_operand 0 "" ""))))]
2693 [(set_attr "type" "br")])
2697 (if_then_else (match_operator 0 "branch_comparison_operator"
2699 "spu_reg_operand" "r")
2705 [(set_attr "type" "br")])
2708 ;; Compare insns are next. Note that the spu has two types of compares,
2709 ;; signed & unsigned, and one type of branch.
2711 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
2712 ;; insns, and branches. We store the operands of compares until we see
2715 (define_expand "cmp<mode>"
2717 (compare (match_operand:VQHSI 0 "spu_reg_operand" "")
2718 (match_operand:VQHSI 1 "spu_nonmem_operand" "")))]
2721 spu_compare_op0 = operands[0];
2722 spu_compare_op1 = operands[1];
2726 (define_expand "cmp<mode>"
2728 (compare (match_operand:DTI 0 "spu_reg_operand" "")
2729 (match_operand:DTI 1 "spu_reg_operand" "")))]
2732 spu_compare_op0 = operands[0];
2733 spu_compare_op1 = operands[1];
2737 (define_expand "cmp<mode>"
2739 (compare (match_operand:VSF 0 "spu_reg_operand" "")
2740 (match_operand:VSF 1 "spu_reg_operand" "")))]
2743 spu_compare_op0 = operands[0];
2744 spu_compare_op1 = operands[1];
2749 ;; branch on condition
2751 (define_expand "beq"
2752 [(use (match_operand 0 "" ""))]
2754 { spu_emit_branch_or_set (0, EQ, operands); DONE; })
2756 (define_expand "bne"
2757 [(use (match_operand 0 "" ""))]
2759 { spu_emit_branch_or_set (0, NE, operands); DONE; })
2761 (define_expand "bge"
2762 [(use (match_operand 0 "" ""))]
2764 { spu_emit_branch_or_set (0, GE, operands); DONE; })
2766 (define_expand "bgt"
2767 [(use (match_operand 0 "" ""))]
2769 { spu_emit_branch_or_set (0, GT, operands); DONE; })
2771 (define_expand "ble"
2772 [(use (match_operand 0 "" ""))]
2774 { spu_emit_branch_or_set (0, LE, operands); DONE; })
2776 (define_expand "blt"
2777 [(use (match_operand 0 "" ""))]
2779 { spu_emit_branch_or_set (0, LT, operands); DONE; })
2781 (define_expand "bgeu"
2782 [(use (match_operand 0 "" ""))]
2784 { spu_emit_branch_or_set (0, GEU, operands); DONE; })
2786 (define_expand "bgtu"
2787 [(use (match_operand 0 "" ""))]
2789 { spu_emit_branch_or_set (0, GTU, operands); DONE; })
2791 (define_expand "bleu"
2792 [(use (match_operand 0 "" ""))]
2794 { spu_emit_branch_or_set (0, LEU, operands); DONE; })
2796 (define_expand "bltu"
2797 [(use (match_operand 0 "" ""))]
2799 { spu_emit_branch_or_set (0, LTU, operands); DONE; })
2804 (define_expand "seq"
2805 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2807 { spu_emit_branch_or_set (1, EQ, operands); DONE; })
2809 (define_expand "sne"
2810 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2812 { spu_emit_branch_or_set (1, NE, operands); DONE; })
2814 (define_expand "sgt"
2815 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2817 { spu_emit_branch_or_set (1, GT, operands); DONE; })
2819 (define_expand "slt"
2820 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2822 { spu_emit_branch_or_set (1, LT, operands); DONE; })
2824 (define_expand "sge"
2825 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2827 { spu_emit_branch_or_set (1, GE, operands); DONE; })
2829 (define_expand "sle"
2830 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2832 { spu_emit_branch_or_set (1, LE, operands); DONE; })
2834 (define_expand "sgtu"
2835 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2837 { spu_emit_branch_or_set (1, GTU, operands); DONE; })
2839 (define_expand "sltu"
2840 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2842 { spu_emit_branch_or_set (1, LTU, operands); DONE; })
2844 (define_expand "sgeu"
2845 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2847 { spu_emit_branch_or_set (1, GEU, operands); DONE; })
2849 (define_expand "sleu"
2850 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2852 { spu_emit_branch_or_set (1, LEU, operands); DONE; })
2857 ;; Define this first one so HAVE_conditional_move is defined.
2858 (define_insn "movcc_dummy"
2859 [(set (match_operand 0 "" "")
2860 (if_then_else (match_operand 1 "" "")
2861 (match_operand 2 "" "")
2862 (match_operand 3 "" "")))]
2866 (define_expand "mov<mode>cc"
2867 [(set (match_operand:ALL 0 "spu_reg_operand" "")
2868 (if_then_else:ALL (match_operand 1 "comparison_operator" "")
2869 (match_operand:ALL 2 "spu_reg_operand" "")
2870 (match_operand:ALL 3 "spu_reg_operand" "")))]
2873 spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
2877 ;; This pattern is used when the result of a compare is not large
2878 ;; enough to use in a selb when expanding conditional moves.
2879 (define_expand "extend_compare"
2880 [(set (match_operand 0 "spu_reg_operand" "=r")
2881 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
2884 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2885 gen_rtx_UNSPEC (GET_MODE (operands[0]),
2886 gen_rtvec (1, operands[1]),
2887 UNSPEC_EXTEND_CMP)));
2891 (define_insn "extend_compare<mode>"
2892 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2893 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
2896 [(set_attr "type" "shuf")])
2901 ;; operand 0 is index
2902 ;; operand 1 is the minimum bound
2903 ;; operand 2 is the maximum bound - minimum bound + 1
2904 ;; operand 3 is CODE_LABEL for the table;
2905 ;; operand 4 is the CODE_LABEL to go to if index out of range.
2906 (define_expand "casesi"
2907 [(match_operand:SI 0 "spu_reg_operand" "")
2908 (match_operand:SI 1 "immediate_operand" "")
2909 (match_operand:SI 2 "immediate_operand" "")
2910 (match_operand 3 "" "")
2911 (match_operand 4 "" "")]
2914 rtx table = gen_reg_rtx (SImode);
2915 rtx index = gen_reg_rtx (SImode);
2916 rtx sindex = gen_reg_rtx (SImode);
2917 rtx addr = gen_reg_rtx (Pmode);
2919 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
2921 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
2922 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
2923 emit_move_insn (addr, gen_rtx_MEM (SImode,
2924 gen_rtx_PLUS (SImode, table, sindex)));
2926 emit_insn (gen_addsi3 (addr, addr, table));
2928 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
2929 emit_jump_insn (gen_tablejump (addr, operands[3]));
2933 (define_insn "tablejump"
2934 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
2935 (use (label_ref (match_operand 1 "" "")))]
2938 [(set_attr "type" "br")])
2943 ;; Note that operand 1 is total size of args, in bytes,
2944 ;; and what the call insn wants is the number of words.
2945 (define_expand "sibcall"
2947 [(call (match_operand:QI 0 "call_operand" "")
2948 (match_operand:QI 1 "" ""))
2952 if (! call_operand (operands[0], QImode))
2953 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2956 (define_insn "_sibcall"
2958 [(call (match_operand:QI 0 "call_operand" "R,S")
2959 (match_operand:QI 1 "" "i,i"))
2961 "SIBLING_CALL_P(insn)"
2965 [(set_attr "type" "br,br")])
2967 (define_expand "sibcall_value"
2969 [(set (match_operand 0 "" "")
2970 (call (match_operand:QI 1 "call_operand" "")
2971 (match_operand:QI 2 "" "")))
2975 if (! call_operand (operands[1], QImode))
2976 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2979 (define_insn "_sibcall_value"
2981 [(set (match_operand 0 "" "")
2982 (call (match_operand:QI 1 "call_operand" "R,S")
2983 (match_operand:QI 2 "" "i,i")))
2985 "SIBLING_CALL_P(insn)"
2989 [(set_attr "type" "br,br")])
2991 ;; Note that operand 1 is total size of args, in bytes,
2992 ;; and what the call insn wants is the number of words.
2993 (define_expand "call"
2995 [(call (match_operand:QI 0 "call_operand" "")
2996 (match_operand:QI 1 "" ""))
2997 (clobber (reg:SI 0))
2998 (clobber (reg:SI 130))])]
3001 if (! call_operand (operands[0], QImode))
3002 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3005 (define_insn "_call"
3007 [(call (match_operand:QI 0 "call_operand" "R,S,T")
3008 (match_operand:QI 1 "" "i,i,i"))
3009 (clobber (reg:SI 0))
3010 (clobber (reg:SI 130))])]
3016 [(set_attr "type" "br")])
3018 (define_expand "call_value"
3020 [(set (match_operand 0 "" "")
3021 (call (match_operand:QI 1 "call_operand" "")
3022 (match_operand:QI 2 "" "")))
3023 (clobber (reg:SI 0))
3024 (clobber (reg:SI 130))])]
3027 if (! call_operand (operands[1], QImode))
3028 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3031 (define_insn "_call_value"
3033 [(set (match_operand 0 "" "")
3034 (call (match_operand:QI 1 "call_operand" "R,S,T")
3035 (match_operand:QI 2 "" "i,i,i")))
3036 (clobber (reg:SI 0))
3037 (clobber (reg:SI 130))])]
3043 [(set_attr "type" "br")])
3045 (define_expand "untyped_call"
3046 [(parallel [(call (match_operand 0 "" "")
3048 (match_operand 1 "" "")
3049 (match_operand 2 "" "")])]
3053 rtx reg = gen_rtx_REG (TImode, 3);
3055 /* We need to use call_value so the return value registers don't get
3057 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
3059 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3061 rtx set = XVECEXP (operands[2], 0, i);
3062 emit_move_insn (SET_DEST (set), SET_SRC (set));
3065 /* The optimizer does not know that the call sets the function value
3066 registers we stored in the result block. We avoid problems by
3067 claiming that all hard registers are used and clobbered at this
3069 emit_insn (gen_blockage ());
3075 ;; Patterns used for splitting and combining.
3078 ;; Function prologue and epilogue.
3080 (define_expand "prologue"
3083 { spu_expand_prologue (); DONE; })
3085 ;; "blockage" is only emited in epilogue. This is what it took to
3086 ;; make "basic block reordering" work with the insns sequence
3087 ;; generated by the spu_expand_epilogue (taken from mips.md)
3089 (define_insn "blockage"
3090 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
3093 [(set_attr "length" "0")])
3095 (define_expand "epilogue"
3098 { spu_expand_epilogue (false); DONE; })
3100 (define_expand "sibcall_epilogue"
3103 { spu_expand_epilogue (true); DONE; })
3106 ;; stack manipulations
3108 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
3109 ;; We move the back-chain and decrement the stack pointer.
3110 (define_expand "allocate_stack"
3111 [(set (match_operand 0 "spu_reg_operand" "")
3112 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
3114 (minus (reg 1) (match_dup 1)))]
3116 "spu_allocate_stack (operands[0], operands[1]); DONE;")
3118 ;; These patterns say how to save and restore the stack pointer. We need not
3119 ;; save the stack pointer at function level since we are careful to preserve
3123 ;; At block level the stack pointer is saved and restored, so that the
3124 ;; stack space allocated within a block is deallocated when leaving
3125 ;; block scope. By default, according to the SPU ABI, the stack
3126 ;; pointer and available stack size are saved in a register. Upon
3127 ;; restoration, the stack pointer is simply copied back, and the
3128 ;; current available stack size is calculated against the restored
3131 ;; For nonlocal gotos, we must save the stack pointer and its
3132 ;; backchain and restore both. Note that in the nonlocal case, the
3133 ;; save area is a memory location.
3135 (define_expand "save_stack_function"
3136 [(match_operand 0 "general_operand" "")
3137 (match_operand 1 "general_operand" "")]
3141 (define_expand "restore_stack_function"
3142 [(match_operand 0 "general_operand" "")
3143 (match_operand 1 "general_operand" "")]
3147 (define_expand "restore_stack_block"
3148 [(match_operand 0 "spu_reg_operand" "")
3149 (match_operand 1 "memory_operand" "")]
3153 spu_restore_stack_block (operands[0], operands[1]);
3157 (define_expand "save_stack_nonlocal"
3158 [(match_operand 0 "memory_operand" "")
3159 (match_operand 1 "spu_reg_operand" "")]
3163 rtx temp = gen_reg_rtx (Pmode);
3165 /* Copy the backchain to the first word, sp to the second. We need to
3166 save the back chain because __builtin_apply appears to clobber it. */
3167 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
3168 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
3169 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
3173 (define_expand "restore_stack_nonlocal"
3174 [(match_operand 0 "spu_reg_operand" "")
3175 (match_operand 1 "memory_operand" "")]
3179 spu_restore_stack_nonlocal(operands[0], operands[1]);
3186 ;; Vector initialization
3187 (define_expand "vec_init<mode>"
3188 [(match_operand:V 0 "register_operand" "")
3189 (match_operand 1 "" "")]
3192 spu_expand_vector_init (operands[0], operands[1]);
3196 (define_expand "vec_set<mode>"
3197 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
3198 (set (match_dup:TI 3)
3199 (unspec:TI [(match_dup:SI 4)
3201 (match_dup:SI 6)] UNSPEC_CPAT))
3202 (set (match_operand:V 0 "spu_reg_operand" "")
3203 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
3205 (match_dup:TI 3)] UNSPEC_SHUFB))]
3208 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
3209 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
3210 operands[3] = gen_reg_rtx (TImode);
3211 operands[4] = stack_pointer_rtx;
3212 operands[5] = offset;
3213 operands[6] = GEN_INT (size);
3216 (define_expand "vec_extract<mode>"
3217 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
3218 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
3219 (parallel [(match_operand 2 "const_int_operand" "i")])))]
3222 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
3224 emit_insn (gen_spu_convert (operands[0], operands[1]));
3229 (define_insn "_vec_extract<mode>"
3230 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
3231 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
3232 (parallel [(match_operand 2 "const_int_operand" "i")])))]
3234 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
3235 [(set_attr "type" "shuf")])
3240 (define_expand "shufb"
3241 [(set (match_operand 0 "spu_reg_operand" "")
3242 (unspec [(match_operand 1 "spu_reg_operand" "")
3243 (match_operand 2 "spu_reg_operand" "")
3244 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
3247 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
3248 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
3253 (define_insn "_shufb"
3254 [(set (match_operand 0 "spu_reg_operand" "=r")
3255 (unspec [(match_operand 1 "spu_reg_operand" "r")
3256 (match_operand 2 "spu_reg_operand" "r")
3257 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
3259 "shufb\t%0,%1,%2,%3"
3260 [(set_attr "type" "shuf")])
3263 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
3266 [(set_attr "type" "nop")])
3269 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
3272 [(set_attr "type" "nop")])
3275 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
3278 [(set_attr "type" "lnop")])
3280 (define_insn "iprefetch"
3281 [(unspec [(const_int 0)] UNSPEC_IPREFETCH)]
3284 [(set_attr "type" "iprefetch")])
3288 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s,s,s")
3289 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
3290 (unspec [(const_int 0)] UNSPEC_HBR)]
3296 [(set_attr "type" "hbr")])
3299 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
3300 (clobber (mem:BLK (scratch)))]
3303 [(set_attr "type" "br")])
3305 (define_insn "syncc"
3306 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
3307 (clobber (mem:BLK (scratch)))]
3310 [(set_attr "type" "br")])
3312 (define_insn "dsync"
3313 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
3314 (clobber (mem:BLK (scratch)))]
3317 [(set_attr "type" "br")])
3320 ;; convert between any two modes, avoiding any GCC assumptions
3321 (define_expand "spu_convert"
3322 [(set (match_operand 0 "spu_reg_operand" "")
3323 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
3326 rtx c = gen__spu_convert (operands[0], operands[1]);
3327 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
3332 (define_insn "_spu_convert"
3333 [(set (match_operand 0 "spu_reg_operand" "=r")
3334 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
3337 [(set_attr "type" "convert")
3338 (set_attr "length" "0")])
3341 [(set (match_operand 0 "spu_reg_operand")
3342 (unspec [(match_operand 1 "spu_reg_operand")] UNSPEC_CONVERT))]
3344 [(use (const_int 0))]
3349 (include "spu-builtins.md")
3352 (define_expand "smaxv4sf3"
3353 [(set (match_operand:V4SF 0 "register_operand" "=r")
3354 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
3355 (match_operand:V4SF 2 "register_operand" "r")))]
3359 rtx mask = gen_reg_rtx (V4SImode);
3361 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
3362 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
3366 (define_expand "sminv4sf3"
3367 [(set (match_operand:V4SF 0 "register_operand" "=r")
3368 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
3369 (match_operand:V4SF 2 "register_operand" "r")))]
3373 rtx mask = gen_reg_rtx (V4SImode);
3375 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
3376 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
3380 (define_expand "vec_widen_umult_hi_v8hi"
3381 [(set (match_operand:V4SI 0 "register_operand" "=r")
3385 (match_operand:V8HI 1 "register_operand" "r")
3386 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
3389 (match_operand:V8HI 2 "register_operand" "r")
3390 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
3394 rtx ve = gen_reg_rtx (V4SImode);
3395 rtx vo = gen_reg_rtx (V4SImode);
3396 rtx mask = gen_reg_rtx (TImode);
3397 unsigned char arr[16] = {
3398 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
3399 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
3401 emit_move_insn (mask, array_to_constant (TImode, arr));
3402 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
3403 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
3404 emit_insn (gen_shufb (operands[0], ve, vo, mask));
3408 (define_expand "vec_widen_umult_lo_v8hi"
3409 [(set (match_operand:V4SI 0 "register_operand" "=r")
3413 (match_operand:V8HI 1 "register_operand" "r")
3414 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
3417 (match_operand:V8HI 2 "register_operand" "r")
3418 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
3422 rtx ve = gen_reg_rtx (V4SImode);
3423 rtx vo = gen_reg_rtx (V4SImode);
3424 rtx mask = gen_reg_rtx (TImode);
3425 unsigned char arr[16] = {
3426 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
3427 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
3429 emit_move_insn (mask, array_to_constant (TImode, arr));
3430 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
3431 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
3432 emit_insn (gen_shufb (operands[0], ve, vo, mask));
3436 (define_expand "vec_widen_smult_hi_v8hi"
3437 [(set (match_operand:V4SI 0 "register_operand" "=r")
3441 (match_operand:V8HI 1 "register_operand" "r")
3442 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
3445 (match_operand:V8HI 2 "register_operand" "r")
3446 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
3450 rtx ve = gen_reg_rtx (V4SImode);
3451 rtx vo = gen_reg_rtx (V4SImode);
3452 rtx mask = gen_reg_rtx (TImode);
3453 unsigned char arr[16] = {
3454 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
3455 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
3457 emit_move_insn (mask, array_to_constant (TImode, arr));
3458 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
3459 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
3460 emit_insn (gen_shufb (operands[0], ve, vo, mask));
3464 (define_expand "vec_widen_smult_lo_v8hi"
3465 [(set (match_operand:V4SI 0 "register_operand" "=r")
3469 (match_operand:V8HI 1 "register_operand" "r")
3470 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
3473 (match_operand:V8HI 2 "register_operand" "r")
3474 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
3478 rtx ve = gen_reg_rtx (V4SImode);
3479 rtx vo = gen_reg_rtx (V4SImode);
3480 rtx mask = gen_reg_rtx (TImode);
3481 unsigned char arr[16] = {
3482 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
3483 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
3485 emit_move_insn (mask, array_to_constant (TImode, arr));
3486 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
3487 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
3488 emit_insn (gen_shufb (operands[0], ve, vo, mask));
3492 (define_expand "vec_realign_load_<mode>"
3493 [(set (match_operand:ALL 0 "register_operand" "=r")
3494 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
3495 (match_operand:ALL 2 "register_operand" "r")
3496 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
3500 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
3504 (define_expand "spu_lvsr"
3505 [(set (match_operand:V16QI 0 "register_operand" "")
3506 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
3511 rtx offset = gen_reg_rtx (V8HImode);
3512 rtx addr_bits = gen_reg_rtx (SImode);
3513 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
3514 rtx splatqi = gen_reg_rtx (TImode);
3515 rtx result = gen_reg_rtx (V8HImode);
3516 unsigned char arr[16] = {
3517 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
3518 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
3519 unsigned char arr2[16] = {
3520 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
3521 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
3523 emit_move_insn (offset, array_to_constant (V8HImode, arr));
3524 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
3526 gcc_assert (GET_CODE (operands[1]) == MEM);
3527 addr = force_reg (Pmode, XEXP (operands[1], 0));
3528 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
3529 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
3531 /* offset - (addr & 0xF)
3532 It is safe to use a single sfh, because each byte of offset is > 15 and
3533 each byte of addr is <= 15. */
3534 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
3536 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
3537 emit_move_insn (operands[0], result);