1 ;; Copyright (C) 2006 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)
147 (include "predicates.md")
148 (include "constraints.md")
153 (define_mode_macro ALL [QI V16QI
161 ; Everything except DI and TI which are handled separately because
162 ; they need different constraints to correctly test VOIDmode constants
163 (define_mode_macro MOV [QI V16QI
170 (define_mode_macro DTI [DI TI])
172 (define_mode_macro VINT [QI V16QI
178 (define_mode_macro VQHSI [QI V16QI
182 (define_mode_macro VHSI [HI V8HI
185 (define_mode_macro VSDF [SF V4SF
188 (define_mode_macro VSI [SI V4SI])
189 (define_mode_macro VDI [DI V2DI])
190 (define_mode_macro VSF [SF V4SF])
191 (define_mode_macro VDF [DF V2DF])
193 (define_mode_attr bh [(QI "b") (V16QI "b")
197 (define_mode_attr d [(SF "") (V4SF "")
198 (DF "d") (V2DF "d")])
199 (define_mode_attr d6 [(SF "6") (V4SF "6")
200 (DF "d") (V2DF "d")])
201 (define_mode_attr f2i [(SF "SI") (V4SF "V4SI")
202 (DF "DI") (V2DF "V2DI")])
204 ;; Used for carry and borrow instructions.
205 (define_mode_macro CBOP [SI DI V4SI V2DI])
207 ;; Used in vec_set and vec_extract
208 (define_mode_macro V [V2DI V4SI V8HI V16QI V2DF V4SF])
209 (define_mode_attr inner [(V16QI "QI")
215 (define_mode_attr vmult [(V16QI "1")
221 (define_mode_attr voff [(V16QI "13")
231 (define_expand "mov<mode>"
232 [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
233 (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
236 if (spu_expand_mov(operands, <MODE>mode))
241 [(set (match_operand 0 "spu_reg_operand")
242 (match_operand 1 "immediate_operand"))]
246 (high (match_dup 1)))
248 (lo_sum (match_dup 0)
251 if (spu_split_immediate (operands))
257 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
258 (match_operand:SI 1 "immediate_operand" "s"))
263 ;; Whenever a function generates the 'pic' pattern above we need to
264 ;; load the pic_offset_table register.
265 ;; GCC doesn't deal well with labels in the middle of a block so we
266 ;; hardcode the offsets in the asm here.
267 (define_insn "load_pic_offset"
268 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
269 (unspec:SI [(const_int 0)] 0))
270 (set (match_operand:SI 1 "spu_reg_operand" "=r")
271 (unspec:SI [(const_int 0)] 0))]
273 "ila\t%1,.+8\;brsl\t%0,4"
274 [(set_attr "length" "8")
275 (set_attr "type" "multi0")])
280 (define_insn "_mov<mode>"
281 [(set (match_operand:MOV 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
282 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
283 "spu_valid_move (operands)"
291 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
294 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
295 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
300 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
301 (lo_sum:SI (match_operand:SI 1 "spu_reg_operand" "0")
302 (match_operand:SI 2 "immediate_operand" "i")))]
306 (define_insn "_movdi"
307 [(set (match_operand:DI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
308 (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
309 "spu_valid_move (operands)"
317 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
319 (define_insn "_movti"
320 [(set (match_operand:TI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
321 (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
322 "spu_valid_move (operands)"
330 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
332 (define_insn_and_split "load"
333 [(set (match_operand 0 "spu_reg_operand" "=r")
334 (match_operand 1 "memory_operand" "m"))
335 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
336 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))]
337 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
342 { spu_split_load(operands); DONE; })
344 (define_insn_and_split "store"
345 [(set (match_operand 0 "memory_operand" "=m")
346 (match_operand 1 "spu_reg_operand" "r"))
347 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
348 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
349 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
354 { spu_split_store(operands); DONE; })
356 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
358 (define_expand "cpat"
359 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
360 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
361 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
362 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
365 rtx x = gen_cpat_const (operands);
368 emit_move_insn (operands[0], x);
374 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
375 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
376 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
377 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
382 [(set_attr "type" "shuf")])
385 [(set (match_operand:TI 0 "spu_reg_operand")
386 (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
387 (match_operand:SI 2 "immediate_operand")
388 (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
390 [(set (match_dup:TI 0)
393 operands[4] = gen_cpat_const (operands);
400 (define_insn "extendqihi2"
401 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
402 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
406 (define_insn "extendhisi2"
407 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
408 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
412 (define_expand "extendsidi2"
413 [(set (match_dup:DI 2)
414 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
415 (set (match_operand:DI 0 "spu_reg_operand" "")
416 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
417 (parallel [(const_int 1)]))))]
420 operands[2] = gen_reg_rtx (DImode);
421 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
425 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
428 (match_operand:V2SI 1 "spu_reg_operand" "r")
429 (parallel [(const_int 1) ]))))]
433 (define_expand "extendqiti2"
434 [(set (match_operand:TI 0 "register_operand" "")
435 (sign_extend:TI (match_operand:QI 1 "register_operand" "")))]
437 "spu_expand_sign_extend(operands);
440 (define_expand "extendhiti2"
441 [(set (match_operand:TI 0 "register_operand" "")
442 (sign_extend:TI (match_operand:HI 1 "register_operand" "")))]
444 "spu_expand_sign_extend(operands);
447 (define_expand "extendsiti2"
448 [(set (match_operand:TI 0 "register_operand" "")
449 (sign_extend:TI (match_operand:SI 1 "register_operand" "")))]
451 "spu_expand_sign_extend(operands);
454 (define_expand "extendditi2"
455 [(set (match_operand:TI 0 "register_operand" "")
456 (sign_extend:TI (match_operand:DI 1 "register_operand" "")))]
458 "spu_expand_sign_extend(operands);
464 (define_insn "zero_extendqihi2"
465 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
466 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
468 "andi\t%0,%1,0x00ff")
470 (define_insn "zero_extendqisi2"
471 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
472 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
474 "andi\t%0,%1,0x00ff")
476 (define_expand "zero_extendhisi2"
477 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
478 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
479 (clobber (match_scratch:SI 2 "=&r"))]
482 rtx mask = gen_reg_rtx (SImode);
483 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
484 emit_move_insn (mask, GEN_INT (0xffff));
485 emit_insn (gen_andsi3(operands[0], op1, mask));
489 (define_insn "zero_extendsidi2"
490 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
491 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
494 [(set_attr "type" "shuf")])
496 (define_insn "zero_extendsiti2"
497 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
498 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
500 "rotqmbyi\t%0,%1,-12"
501 [(set_attr "type" "shuf")])
503 (define_insn "zero_extendditi2"
504 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
505 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
508 [(set_attr "type" "shuf")])
513 (define_insn "truncdiqi2"
514 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
515 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
518 [(set_attr "type" "shuf")])
520 (define_insn "truncdihi2"
521 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
522 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
525 [(set_attr "type" "shuf")])
527 (define_insn "truncdisi2"
528 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
529 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
532 [(set_attr "type" "shuf")])
534 (define_insn "trunctiqi2"
535 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
536 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
539 [(set_attr "type" "shuf")])
541 (define_insn "trunctihi2"
542 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
543 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
546 [(set_attr "type" "shuf")])
548 (define_insn "trunctisi2"
549 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
550 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
553 [(set_attr "type" "shuf")])
555 (define_insn "trunctidi2"
556 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
557 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
560 [(set_attr "type" "shuf")])
565 (define_insn "floatsisf2"
566 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
567 (float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
570 [(set_attr "type" "fp7")])
572 (define_insn "floatv4siv4sf2"
573 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
574 (float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
577 [(set_attr "type" "fp7")])
579 (define_insn "fix_truncsfsi2"
580 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
581 (fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
584 [(set_attr "type" "fp7")])
586 (define_insn "fix_truncv4sfv4si2"
587 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
588 (fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
591 [(set_attr "type" "fp7")])
593 (define_insn "floatunssisf2"
594 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
595 (unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
598 [(set_attr "type" "fp7")])
600 (define_insn "floatunsv4siv4sf2"
601 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
602 (unsigned_float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
605 [(set_attr "type" "fp7")])
607 (define_insn "fixuns_truncsfsi2"
608 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
609 (unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
612 [(set_attr "type" "fp7")])
614 (define_insn "fixuns_truncv4sfv4si2"
615 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
616 (unsigned_fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
619 [(set_attr "type" "fp7")])
621 (define_insn "extendsfdf2"
622 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
623 (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))]
626 [(set_attr "type" "fpd")])
628 (define_insn "truncdfsf2"
629 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
630 (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))]
633 [(set_attr "type" "fpd")])
635 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
636 (define_expand "floatsidf2"
637 [(set (match_operand:DF 0 "register_operand" "")
638 (float:DF (match_operand:SI 1 "register_operand" "")))]
642 rtx c0 = gen_reg_rtx (SImode);
643 rtx c1 = gen_reg_rtx (DFmode);
644 rtx r0 = gen_reg_rtx (SImode);
645 rtx r1 = gen_reg_rtx (DFmode);
647 emit_move_insn (c0, GEN_INT (-0x80000000ll));
648 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
650 emit_insn (gen_xorsi3 (r0, operands[1], c0));
654 emit_library_call_value (ufloat_optab->handlers[DFmode][SImode].libfunc,
655 NULL_RTX, LCT_NORMAL, DFmode, 1, r0, SImode);
656 insns = get_insns ();
658 emit_libcall_block (insns, r1, value,
659 gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
661 emit_insn (gen_subdf3 (operands[0], r1, c1));
665 (define_expand "floatdidf2"
666 [(set (match_operand:DF 0 "register_operand" "")
667 (float:DF (match_operand:DI 1 "register_operand" "")))]
671 rtx c0 = gen_reg_rtx (DImode);
672 rtx r0 = gen_reg_rtx (DImode);
673 rtx r1 = gen_reg_rtx (DFmode);
674 rtx r2 = gen_reg_rtx (DImode);
675 rtx setneg = gen_reg_rtx (DImode);
676 rtx isneg = gen_reg_rtx (SImode);
677 rtx neg = gen_reg_rtx (DImode);
678 rtx mask = gen_reg_rtx (DImode);
680 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
682 emit_insn (gen_negdi2 (neg, operands[1]));
683 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
684 emit_insn (gen_extend_compare (mask, isneg));
685 emit_insn (gen_selb (r0, neg, operands[1], mask));
686 emit_insn (gen_andc_di (setneg, c0, mask));
691 emit_library_call_value (ufloat_optab->handlers[DFmode][DImode].libfunc,
692 NULL_RTX, LCT_NORMAL, DFmode, 1, r0, DImode);
693 insns = get_insns ();
695 emit_libcall_block (insns, r1, value,
696 gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
698 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
699 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
705 (define_expand "addv16qi3"
706 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
707 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
708 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
711 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
712 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
713 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
714 rtx rhs_and = gen_reg_rtx (V8HImode);
715 rtx hi_char = gen_reg_rtx (V8HImode);
716 rtx lo_char = gen_reg_rtx (V8HImode);
717 rtx mask = gen_reg_rtx (V8HImode);
719 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
720 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
721 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
722 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
723 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
727 (define_insn "add<mode>3"
728 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
729 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
730 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
736 (define_expand "add<mode>3"
737 [(set (match_dup:VDI 3)
738 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
739 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
740 (set (match_dup:VDI 5)
741 (unspec:VDI [(match_dup 3)
743 (match_dup:TI 4)] UNSPEC_SHUFB))
744 (set (match_operand:VDI 0 "spu_reg_operand" "")
745 (unspec:VDI [(match_dup 1)
747 (match_dup 5)] UNSPEC_ADDX))]
750 unsigned char pat[16] = {
751 0x04, 0x05, 0x06, 0x07,
752 0x80, 0x80, 0x80, 0x80,
753 0x0c, 0x0d, 0x0e, 0x0f,
754 0x80, 0x80, 0x80, 0x80
756 operands[3] = gen_reg_rtx (<MODE>mode);
757 operands[4] = gen_reg_rtx (TImode);
758 operands[5] = gen_reg_rtx (<MODE>mode);
759 emit_move_insn (operands[4], array_to_constant (TImode, pat));
762 (define_insn "cg_<mode>"
763 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
764 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
765 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
769 (define_insn "cgx_<mode>"
770 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
771 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
772 (match_operand 2 "spu_reg_operand" "r")
773 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
777 (define_insn "addx_<mode>"
778 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
779 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
780 (match_operand 2 "spu_reg_operand" "r")
781 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
786 ;; This is not the most efficient implementation of addti3.
787 ;; We include this here because 1) the compiler needs it to be
788 ;; defined as the word size is 128-bit and 2) sometimes gcc
789 ;; substitutes an add for a constant left-shift. 2) is unlikely
790 ;; because we also give addti3 a high cost. In case gcc does
791 ;; generate TImode add, here is the code to do it.
792 ;; operand 2 is a nonmemory because the compiler requires it.
793 (define_insn "addti3"
794 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
795 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
796 (match_operand:TI 2 "spu_nonmem_operand" "r")))
797 (clobber (match_scratch:TI 3 "=&r"))]
806 [(set_attr "type" "multi0")
807 (set_attr "length" "28")])
809 (define_insn "add<mode>3"
810 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
811 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
812 (match_operand:VSF 2 "spu_reg_operand" "r")))]
815 [(set_attr "type" "fp6")])
817 (define_insn "add<mode>3"
818 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
819 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
820 (match_operand:VDF 2 "spu_reg_operand" "r")))]
823 [(set_attr "type" "fpd")])
828 (define_expand "subv16qi3"
829 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
830 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
831 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
834 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
835 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
836 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
837 rtx rhs_and = gen_reg_rtx (V8HImode);
838 rtx hi_char = gen_reg_rtx (V8HImode);
839 rtx lo_char = gen_reg_rtx (V8HImode);
840 rtx mask = gen_reg_rtx (V8HImode);
842 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
843 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
844 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
845 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
846 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
850 (define_insn "sub<mode>3"
851 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
852 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
853 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
859 (define_expand "sub<mode>3"
860 [(set (match_dup:VDI 3)
861 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
862 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
863 (set (match_dup:VDI 5)
864 (unspec:VDI [(match_dup 3)
866 (match_dup:TI 4)] UNSPEC_SHUFB))
867 (set (match_operand:VDI 0 "spu_reg_operand" "")
868 (unspec:VDI [(match_dup 1)
870 (match_dup 5)] UNSPEC_SFX))]
873 unsigned char pat[16] = {
874 0x04, 0x05, 0x06, 0x07,
875 0xc0, 0xc0, 0xc0, 0xc0,
876 0x0c, 0x0d, 0x0e, 0x0f,
877 0xc0, 0xc0, 0xc0, 0xc0
879 operands[3] = gen_reg_rtx (<MODE>mode);
880 operands[4] = gen_reg_rtx (TImode);
881 operands[5] = gen_reg_rtx (<MODE>mode);
882 emit_move_insn (operands[4], array_to_constant (TImode, pat));
885 (define_insn "bg_<mode>"
886 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
887 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
888 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
892 (define_insn "bgx_<mode>"
893 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
894 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
895 (match_operand 2 "spu_reg_operand" "r")
896 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
900 (define_insn "sfx_<mode>"
901 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
902 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
903 (match_operand 2 "spu_reg_operand" "r")
904 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
908 (define_insn "subti3"
909 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
910 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
911 (match_operand:TI 2 "spu_reg_operand" "r")))
912 (clobber (match_scratch:TI 3 "=&r"))
913 (clobber (match_scratch:TI 4 "=&r"))
914 (clobber (match_scratch:TI 5 "=&r"))]
925 [(set_attr "type" "multi0")
926 (set_attr "length" "36")])
928 (define_insn "sub<mode>3"
929 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
930 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
931 (match_operand:VSF 2 "spu_reg_operand" "r")))]
934 [(set_attr "type" "fp6")])
936 (define_insn "sub<mode>3"
937 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
938 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
939 (match_operand:VDF 2 "spu_reg_operand" "r")))]
942 [(set_attr "type" "fpd")])
947 (define_expand "negv16qi2"
948 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
949 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
952 rtx zero = gen_reg_rtx (V16QImode);
953 emit_move_insn (zero, CONST0_RTX (V16QImode));
954 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
958 (define_insn "neg<mode>2"
959 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
960 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
964 (define_expand "negdi2"
965 [(set (match_operand:DI 0 "spu_reg_operand" "")
966 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
969 rtx zero = gen_reg_rtx(DImode);
970 emit_move_insn(zero, GEN_INT(0));
971 emit_insn(gen_subdi3(operands[0], zero, operands[1]));
975 (define_expand "negti2"
976 [(set (match_operand:TI 0 "spu_reg_operand" "")
977 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
980 rtx zero = gen_reg_rtx(TImode);
981 emit_move_insn(zero, GEN_INT(0));
982 emit_insn(gen_subti3(operands[0], zero, operands[1]));
986 (define_expand "neg<mode>2"
988 [(set (match_operand:VSF 0 "spu_reg_operand" "")
989 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
990 (use (match_dup 2))])]
992 "operands[2] = gen_reg_rtx (<f2i>mode);
993 emit_move_insn (operands[2], spu_const (<f2i>mode, -0x80000000ull));")
995 (define_expand "neg<mode>2"
997 [(set (match_operand:VDF 0 "spu_reg_operand" "")
998 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
999 (use (match_dup 2))])]
1001 "operands[2] = gen_reg_rtx (<f2i>mode);
1002 emit_move_insn (operands[2], spu_const (<f2i>mode, -0x8000000000000000ull));")
1004 (define_insn_and_split "_neg<mode>2"
1005 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1006 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1007 (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
1011 [(set (match_dup:<f2i> 3)
1012 (xor:<f2i> (match_dup:<f2i> 4)
1013 (match_dup:<f2i> 2)))]
1015 operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
1016 operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
1022 (define_expand "abs<mode>2"
1024 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1025 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1026 (use (match_dup 2))])]
1028 "operands[2] = gen_reg_rtx (<f2i>mode);
1029 emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffull));")
1031 (define_expand "abs<mode>2"
1033 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1034 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1035 (use (match_dup 2))])]
1037 "operands[2] = gen_reg_rtx (<f2i>mode);
1038 emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffffffffffull));")
1040 (define_insn_and_split "_abs<mode>2"
1041 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1042 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1043 (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
1047 [(set (match_dup:<f2i> 3)
1048 (and:<f2i> (match_dup:<f2i> 4)
1049 (match_dup:<f2i> 2)))]
1051 operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
1052 operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
1058 (define_insn "mulhi3"
1059 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1060 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1061 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1066 [(set_attr "type" "fp7")])
1068 (define_expand "mulv8hi3"
1069 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1070 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1071 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1074 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1075 rtx low = gen_reg_rtx (V4SImode);
1076 rtx high = gen_reg_rtx (V4SImode);
1077 rtx shift = gen_reg_rtx (V4SImode);
1078 rtx mask = gen_reg_rtx (V4SImode);
1080 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1081 emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1082 emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1083 emit_insn (gen_ashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1084 emit_insn (gen_selb (result, shift, low, mask));
1088 (define_expand "mul<mode>3"
1090 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1091 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1092 (match_operand:VSI 2 "spu_reg_operand" "")))
1093 (clobber (match_dup:VSI 3))
1094 (clobber (match_dup:VSI 4))
1095 (clobber (match_dup:VSI 5))
1096 (clobber (match_dup:VSI 6))])]
1099 operands[3] = gen_reg_rtx(<MODE>mode);
1100 operands[4] = gen_reg_rtx(<MODE>mode);
1101 operands[5] = gen_reg_rtx(<MODE>mode);
1102 operands[6] = gen_reg_rtx(<MODE>mode);
1105 (define_insn_and_split "_mulsi3"
1106 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1107 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1108 (match_operand:SI 2 "spu_arith_operand" "rK")))
1109 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1110 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1111 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1112 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1116 [(set (match_dup:SI 0)
1117 (mult:SI (match_dup:SI 1)
1120 HOST_WIDE_INT val = 0;
1121 rtx a = operands[3];
1122 rtx b = operands[4];
1123 rtx c = operands[5];
1124 rtx d = operands[6];
1125 if (GET_CODE(operands[2]) == CONST_INT)
1127 val = INTVAL(operands[2]);
1128 emit_move_insn(d, operands[2]);
1131 if (val && (val & 0xffff) == 0)
1133 emit_insn(gen_mpyh_si(operands[0], operands[2], operands[1]));
1135 else if (val > 0 && val < 0x10000)
1137 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1138 emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
1139 emit_insn(gen_mpyu_si(c, operands[1], cst));
1140 emit_insn(gen_addsi3(operands[0], a, c));
1144 emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
1145 emit_insn(gen_mpyh_si(b, operands[2], operands[1]));
1146 emit_insn(gen_mpyu_si(c, operands[1], operands[2]));
1147 emit_insn(gen_addsi3(d, a, b));
1148 emit_insn(gen_addsi3(operands[0], d, c));
1153 (define_insn_and_split "_mulv4si3"
1154 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1155 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1156 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1157 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1158 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1159 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1160 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1164 [(set (match_dup:V4SI 0)
1165 (mult:V4SI (match_dup:V4SI 1)
1166 (match_dup:V4SI 2)))]
1168 rtx a = operands[3];
1169 rtx b = operands[4];
1170 rtx c = operands[5];
1171 rtx d = operands[6];
1172 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1173 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1174 emit_insn(gen_spu_mpyh(a, op1, op2));
1175 emit_insn(gen_spu_mpyh(b, op2, op1));
1176 emit_insn(gen_spu_mpyu(c, op1, op2));
1177 emit_insn(gen_addv4si3(d, a, b));
1178 emit_insn(gen_addv4si3(operands[0], d, c));
1182 (define_insn "mulhisi3"
1183 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1184 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1185 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1188 [(set_attr "type" "fp7")])
1190 (define_insn "mulhisi3_imm"
1191 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1192 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1193 (match_operand:SI 2 "immediate_operand" "K")))]
1196 [(set_attr "type" "fp7")])
1198 (define_insn "umulhisi3"
1199 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1200 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1201 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1204 [(set_attr "type" "fp7")])
1206 (define_insn "umulhisi3_imm"
1207 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1208 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1209 (and:SI (match_operand:SI 2 "immediate_operand" "K") (const_int 65535))))]
1212 [(set_attr "type" "fp7")])
1214 (define_insn "mpyu_si"
1215 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1216 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1218 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1219 (const_int 65535))))]
1224 [(set_attr "type" "fp7")])
1226 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1227 ;; It's faster to do the multiplies in parallel then add them. If we
1228 ;; merge a multiply and add it prevents the multiplies from happening in
1230 (define_insn "mpya_si"
1231 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1232 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1233 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1234 (match_operand:SI 3 "spu_reg_operand" "r")))]
1237 [(set_attr "type" "fp7")])
1239 (define_insn "mpyh_si"
1240 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1241 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1243 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1244 (const_int 65535))))]
1247 [(set_attr "type" "fp7")])
1249 (define_insn "mpys_si"
1250 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1252 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1253 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1257 [(set_attr "type" "fp7")])
1259 (define_insn "mpyhh_si"
1260 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1261 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1263 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1267 [(set_attr "type" "fp7")])
1269 (define_insn "mpyhhu_si"
1270 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1271 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1273 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1277 [(set_attr "type" "fp7")])
1279 (define_insn "mpyhha_si"
1280 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1281 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1283 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1285 (match_operand:SI 3 "spu_reg_operand" "0")))]
1288 [(set_attr "type" "fp7")])
1290 (define_insn "mul<mode>3"
1291 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1292 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1293 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1296 [(set_attr "type" "fp<d6>")])
1298 (define_insn "fma_<mode>"
1299 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1300 (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1301 (match_operand:VSF 2 "spu_reg_operand" "r"))
1302 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1305 [(set_attr "type" "fp6")])
1307 (define_insn "fnms_<mode>"
1308 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1309 (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1310 (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1311 (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1314 [(set_attr "type" "fp6")])
1316 (define_insn "fms_<mode>"
1317 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1318 (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1319 (match_operand:VSF 2 "spu_reg_operand" "r"))
1320 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1323 [(set_attr "type" "fp6")])
1325 (define_insn "fma_<mode>"
1326 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1327 (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1328 (match_operand:VDF 2 "spu_reg_operand" "r"))
1329 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1332 [(set_attr "type" "fpd")])
1334 (define_insn "fnma_<mode>"
1335 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1336 (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1337 (match_operand:VDF 2 "spu_reg_operand" "r"))
1338 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1341 [(set_attr "type" "fpd")])
1343 (define_insn "fnms_<mode>"
1344 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1345 (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1346 (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1347 (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1350 [(set_attr "type" "fpd")])
1352 (define_insn "fms_<mode>"
1353 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1354 (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1355 (match_operand:VDF 2 "spu_reg_operand" "r"))
1356 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1359 [(set_attr "type" "fpd")])
1362 ;; mul highpart, used for divide by constant optimizations.
1364 (define_expand "smulsi3_highpart"
1365 [(set (match_operand:SI 0 "register_operand" "")
1368 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1369 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1373 rtx t0 = gen_reg_rtx (SImode);
1374 rtx t1 = gen_reg_rtx (SImode);
1375 rtx t2 = gen_reg_rtx (SImode);
1376 rtx t3 = gen_reg_rtx (SImode);
1377 rtx t4 = gen_reg_rtx (SImode);
1378 rtx t5 = gen_reg_rtx (SImode);
1379 rtx t6 = gen_reg_rtx (SImode);
1380 rtx t7 = gen_reg_rtx (SImode);
1381 rtx t8 = gen_reg_rtx (SImode);
1382 rtx t9 = gen_reg_rtx (SImode);
1383 rtx t11 = gen_reg_rtx (SImode);
1384 rtx t12 = gen_reg_rtx (SImode);
1385 rtx t14 = gen_reg_rtx (SImode);
1386 rtx t15 = gen_reg_rtx (HImode);
1387 rtx t16 = gen_reg_rtx (HImode);
1388 rtx t17 = gen_reg_rtx (HImode);
1389 rtx t18 = gen_reg_rtx (HImode);
1390 rtx t19 = gen_reg_rtx (SImode);
1391 rtx t20 = gen_reg_rtx (SImode);
1392 rtx t21 = gen_reg_rtx (SImode);
1393 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1394 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1395 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1396 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1398 emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1399 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1400 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1401 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1402 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1403 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1404 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1405 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1407 /* Gen carry bits (in t9 and t11). */
1408 emit_insn (gen_addsi3 (t8, t2, t3));
1409 emit_insn (gen_cg_si (t9, t2, t3));
1410 emit_insn (gen_cg_si (t11, t8, t4));
1412 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1413 emit_insn (gen_addx_si (t12, t5, t6, t9));
1414 emit_insn (gen_addx_si (t14, t12, t7, t11));
1416 /* mpys treats both operands as signed when we really want it to treat
1417 the first operand as signed and the second operand as unsigned.
1418 The code below corrects for that difference. */
1419 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1420 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1421 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1422 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1423 emit_insn (gen_extendhisi2 (t19, t17));
1424 emit_insn (gen_extendhisi2 (t20, t18));
1425 emit_insn (gen_addsi3 (t21, t19, t20));
1426 emit_insn (gen_addsi3 (operands[0], t14, t21));
1430 (define_expand "umulsi3_highpart"
1431 [(set (match_operand:SI 0 "register_operand" "")
1434 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1435 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1440 rtx t0 = gen_reg_rtx (SImode);
1441 rtx t1 = gen_reg_rtx (SImode);
1442 rtx t2 = gen_reg_rtx (SImode);
1443 rtx t3 = gen_reg_rtx (SImode);
1444 rtx t4 = gen_reg_rtx (SImode);
1445 rtx t5 = gen_reg_rtx (SImode);
1446 rtx t6 = gen_reg_rtx (SImode);
1447 rtx t7 = gen_reg_rtx (SImode);
1448 rtx t8 = gen_reg_rtx (SImode);
1449 rtx t9 = gen_reg_rtx (SImode);
1450 rtx t10 = gen_reg_rtx (SImode);
1451 rtx t12 = gen_reg_rtx (SImode);
1452 rtx t13 = gen_reg_rtx (SImode);
1453 rtx t14 = gen_reg_rtx (SImode);
1454 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1455 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1456 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1458 emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1459 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1460 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1461 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1462 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1463 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1464 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1465 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1466 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1468 /* Gen carry bits (in t10 and t12). */
1469 emit_insn (gen_addsi3 (t9, t1, t5));
1470 emit_insn (gen_cg_si (t10, t1, t5));
1471 emit_insn (gen_cg_si (t12, t9, t6));
1473 /* Gen high 32 bits in operand[0]. */
1474 emit_insn (gen_addx_si (t13, t4, t7, t10));
1475 emit_insn (gen_addx_si (t14, t13, t8, t12));
1476 emit_insn (gen_movsi (operands[0], t14));
1483 ;; Not necessarily the best implementation of divide but faster then
1484 ;; the default that gcc provides because this is inlined and it uses
1486 (define_insn "divmodsi4"
1487 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1488 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1489 (match_operand:SI 2 "spu_reg_operand" "r")))
1490 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1491 (mod:SI (match_dup 1)
1493 (clobber (match_scratch:SI 4 "=&r"))
1494 (clobber (match_scratch:SI 5 "=&r"))
1495 (clobber (match_scratch:SI 6 "=&r"))
1496 (clobber (match_scratch:SI 7 "=&r"))
1497 (clobber (match_scratch:SI 8 "=&r"))
1498 (clobber (match_scratch:SI 9 "=&r"))
1499 (clobber (match_scratch:SI 10 "=&r"))
1500 (clobber (match_scratch:SI 11 "=&r"))
1501 (clobber (match_scratch:SI 12 "=&r"))
1502 (clobber (reg:SI 130))]
1510 selb %8,%8,%1,%10\\n\\
1511 selb %9,%9,%2,%11\\n\\
1517 shlqbyi %3,%8,0\\n\\
1518 xor %11,%10,%11\\n\\
1522 1: or %12,%0,%5\\n\\
1523 rotqmbii %5,%5,-1\\n\\
1527 rotqmbii %4,%4,-1\\n\\
1528 selb %0,%12,%0,%6\\n\\
1530 selb %3,%7,%3,%6\\n\\
1534 selb %3,%8,%3,%10\\n\\
1536 [(set_attr "type" "multi0")
1537 (set_attr "length" "128")])
1539 (define_insn "udivmodsi4"
1540 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1541 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1542 (match_operand:SI 2 "spu_reg_operand" "r")))
1543 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1544 (umod:SI (match_dup 1)
1546 (clobber (match_scratch:SI 4 "=&r"))
1547 (clobber (match_scratch:SI 5 "=&r"))
1548 (clobber (match_scratch:SI 6 "=&r"))
1549 (clobber (match_scratch:SI 7 "=&r"))
1550 (clobber (match_scratch:SI 8 "=&r"))
1551 (clobber (reg:SI 130))]
1564 rotqmbii %5,%5,-1\\n\\
1568 rotqmbii %4,%4,-1\\n\\
1569 selb %0,%8,%0,%6\\n\\
1571 selb %3,%7,%3,%6\\n\\
1574 [(set_attr "type" "multi0")
1575 (set_attr "length" "80")])
1577 (define_insn_and_split "div<mode>3"
1578 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1579 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1580 (match_operand:VSF 2 "spu_reg_operand" "r")))
1581 (clobber (match_scratch:VSF 3 "=&r"))
1582 (clobber (match_scratch:VSF 4 "=&r"))]
1586 [(set (match_dup:VSF 0)
1587 (div:VSF (match_dup:VSF 1)
1589 (clobber (match_dup:VSF 3))
1590 (clobber (match_dup:VSF 4))]
1592 emit_insn(gen_frest_<mode>(operands[3], operands[2]));
1593 emit_insn(gen_fi_<mode>(operands[3], operands[2], operands[3]));
1594 emit_insn(gen_mul<mode>3(operands[4], operands[1], operands[3]));
1595 emit_insn(gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
1596 emit_insn(gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
1603 (define_insn_and_split "sqrtsf2"
1604 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1605 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1606 (clobber (match_scratch:SF 2 "=&r"))
1607 (clobber (match_scratch:SF 3 "=&r"))
1608 (clobber (match_scratch:SF 4 "=&r"))
1609 (clobber (match_scratch:SF 5 "=&r"))]
1613 [(set (match_dup:SF 0)
1614 (sqrt:SF (match_dup:SF 1)))
1615 (clobber (match_dup:SF 2))
1616 (clobber (match_dup:SF 3))
1617 (clobber (match_dup:SF 4))
1618 (clobber (match_dup:SF 5))]
1620 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1621 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1622 emit_insn(gen_frsqest_sf(operands[2],operands[1]));
1623 emit_insn(gen_fi_sf(operands[2],operands[1],operands[2]));
1624 emit_insn(gen_mulsf3(operands[5],operands[2],operands[1]));
1625 emit_insn(gen_mulsf3(operands[3],operands[5],operands[3]));
1626 emit_insn(gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1627 emit_insn(gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1631 (define_insn "frest_<mode>"
1632 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1633 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1636 [(set_attr "type" "shuf")])
1638 (define_insn "frsqest_<mode>"
1639 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1640 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1643 [(set_attr "type" "shuf")])
1645 (define_insn "fi_<mode>"
1646 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1647 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1648 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1651 [(set_attr "type" "fp7")])
1656 (define_insn "and<mode>3"
1657 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1658 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1659 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1663 and%j2i\t%0,%1,%J2")
1665 (define_insn "anddi3"
1666 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1667 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1668 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1672 and%k2i\t%0,%1,%K2")
1674 (define_insn "andti3"
1675 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1676 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1677 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1681 and%m2i\t%0,%1,%L2")
1683 (define_insn "andc_<mode>"
1684 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1685 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1686 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1690 (define_insn "nand_<mode>"
1691 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1692 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1693 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1700 (define_insn "ior<mode>3"
1701 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1702 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
1703 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
1710 (define_insn "iordi3"
1711 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
1712 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
1713 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
1720 (define_insn "iorti3"
1721 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
1722 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
1723 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
1730 (define_insn "orc_<mode>"
1731 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1732 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1733 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1737 (define_insn "nor_<mode>"
1738 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1739 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1740 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1746 (define_insn "xor<mode>3"
1747 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1748 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1749 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
1753 xor%j2i\t%0,%1,%S2")
1755 (define_insn "xordi3"
1756 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1757 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1758 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1762 xor%k2i\t%0,%1,%K2")
1764 (define_insn "xorti3"
1765 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1766 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1767 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1771 xor%m2i\t%0,%1,%L2")
1773 (define_insn "eqv_<mode>"
1774 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1775 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1776 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1782 (define_insn "one_cmpl<mode>2"
1783 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1784 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
1791 (define_expand "selb"
1792 [(set (match_operand 0 "spu_reg_operand" "")
1793 (unspec [(match_operand 1 "spu_reg_operand" "")
1794 (match_operand 2 "spu_reg_operand" "")
1795 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
1798 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
1799 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
1804 ;; This could be defined as a combination of logical operations, but at
1805 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
1806 (define_insn "_selb"
1807 [(set (match_operand 0 "spu_reg_operand" "=r")
1808 (unspec [(match_operand 1 "spu_reg_operand" "r")
1809 (match_operand 2 "spu_reg_operand" "r")
1810 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
1811 "GET_MODE(operands[0]) == GET_MODE(operands[1])
1812 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
1813 "selb\t%0,%1,%2,%3")
1816 ;; Misc. byte/bit operations
1817 ;; clz/ctz/ffs/popcount/parity
1820 (define_insn "clz<mode>2"
1821 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
1822 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
1826 (define_expand "ctz<mode>2"
1828 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
1829 (set (match_dup 3) (and:VSI (match_dup 1)
1831 (set (match_dup 4) (clz:VSI (match_dup 3)))
1832 (set (match_operand:VSI 0 "spu_reg_operand" "")
1833 (minus:VSI (match_dup 5) (match_dup 4)))]
1836 operands[2] = gen_reg_rtx (<MODE>mode);
1837 operands[3] = gen_reg_rtx (<MODE>mode);
1838 operands[4] = gen_reg_rtx (<MODE>mode);
1839 operands[5] = spu_const(<MODE>mode, 31);
1842 (define_expand "ffs<mode>2"
1844 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
1845 (set (match_dup 3) (and:VSI (match_dup 1)
1847 (set (match_dup 4) (clz:VSI (match_dup 3)))
1848 (set (match_operand:VSI 0 "spu_reg_operand" "")
1849 (minus:VSI (match_dup 5) (match_dup 4)))]
1852 operands[2] = gen_reg_rtx (<MODE>mode);
1853 operands[3] = gen_reg_rtx (<MODE>mode);
1854 operands[4] = gen_reg_rtx (<MODE>mode);
1855 operands[5] = spu_const(<MODE>mode, 32);
1858 (define_expand "popcountsi2"
1860 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
1863 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
1864 (set (match_operand:SI 0 "spu_reg_operand" "")
1865 (sign_extend:SI (match_dup 3)))]
1868 operands[2] = gen_reg_rtx (SImode);
1869 operands[3] = gen_reg_rtx (HImode);
1872 (define_expand "paritysi2"
1873 [(set (match_operand:SI 0 "spu_reg_operand" "")
1874 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
1877 operands[2] = gen_reg_rtx (SImode);
1878 emit_insn (gen_popcountsi2(operands[2], operands[1]));
1879 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
1883 (define_insn "cntb_si"
1884 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1885 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
1889 [(set_attr "type" "fxb")])
1891 (define_insn "cntb_v16qi"
1892 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1893 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
1897 [(set_attr "type" "fxb")])
1899 (define_insn "sumb_si"
1900 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
1901 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
1904 [(set_attr "type" "fxb")])
1909 (define_insn "ashl<mode>3"
1910 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1911 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1912 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
1917 [(set_attr "type" "fx3")])
1919 (define_insn_and_split "ashldi3"
1920 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1921 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1922 (match_operand:SI 2 "spu_shift_operand" "r,I")))
1923 (clobber (match_scratch:SI 3 "=&r,X"))]
1927 [(set (match_dup:DI 0)
1928 (ashift:DI (match_dup:DI 1)
1931 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
1932 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
1933 rtx op2 = operands[2];
1934 rtx op3 = operands[3];
1936 if (GET_CODE (operands[2]) == REG)
1938 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
1939 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
1940 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
1941 emit_insn (gen_shlqbi_ti (op0, op0, op3));
1945 HOST_WIDE_INT val = INTVAL (operands[2]);
1946 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
1947 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
1949 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
1954 (define_expand "ashlti3"
1955 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
1956 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
1957 (match_operand:SI 2 "spu_nonmem_operand" "")))
1958 (clobber (match_dup:TI 3))])]
1960 "if (GET_CODE (operands[2]) == CONST_INT)
1962 emit_insn(gen_ashlti3_imm(operands[0], operands[1], operands[2]));
1965 operands[3] = gen_reg_rtx (TImode);")
1967 (define_insn_and_split "ashlti3_imm"
1968 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1969 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1970 (match_operand:SI 2 "immediate_operand" "O,P")))]
1975 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
1976 [(set (match_dup:TI 0)
1977 (ashift:TI (match_dup:TI 1)
1979 (set (match_dup:TI 0)
1980 (ashift:TI (match_dup:TI 0)
1983 HOST_WIDE_INT val = INTVAL(operands[2]);
1984 operands[3] = GEN_INT (val&7);
1985 operands[4] = GEN_INT (val&0x78);
1987 [(set_attr "type" "shuf,shuf")])
1989 (define_insn_and_split "ashlti3_reg"
1990 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1991 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
1992 (match_operand:SI 2 "spu_reg_operand" "r")))
1993 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
1997 [(set (match_dup:TI 3)
1998 (ashift:TI (match_dup:TI 1)
1999 (and:SI (match_dup:SI 2)
2001 (set (match_dup:TI 0)
2002 (ashift:TI (match_dup:TI 3)
2003 (and:SI (match_dup:SI 2)
2007 (define_insn "shlqbybi_ti"
2008 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2009 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2010 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2015 shlqbyi\t%0,%1,%2/8"
2016 [(set_attr "type" "shuf,shuf")])
2018 (define_insn "shlqbi_ti"
2019 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2020 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2021 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2027 [(set_attr "type" "shuf,shuf")])
2029 (define_insn "shlqby_ti"
2030 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2031 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2032 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2038 [(set_attr "type" "shuf,shuf")])
2043 (define_insn_and_split "lshr<mode>3"
2044 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2045 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2046 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
2047 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2051 rot<bh>mi\t%0,%1,%N2"
2052 "reload_completed && GET_CODE (operands[2]) == REG"
2053 [(set (match_dup:VHSI 3)
2054 (neg:VHSI (match_dup:VHSI 2)))
2055 (set (match_dup:VHSI 0)
2056 (lshiftrt:VHSI (match_dup:VHSI 1)
2057 (neg:VHSI (match_dup:VHSI 3))))]
2059 [(set_attr "type" "*,fx3")])
2062 (define_insn "rotm_<mode>"
2063 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2064 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2065 (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
2069 rot<bh>mi\t%0,%1,%2"
2070 [(set_attr "type" "fx3")])
2072 (define_expand "lshr<mode>3"
2073 [(parallel [(set (match_operand:DTI 0 "spu_reg_operand" "")
2074 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "")
2075 (match_operand:SI 2 "spu_nonmem_operand" "")))
2076 (clobber (match_dup:DTI 3))
2077 (clobber (match_dup:SI 4))
2078 (clobber (match_dup:SI 5))])]
2080 "if (GET_CODE (operands[2]) == CONST_INT)
2082 emit_insn(gen_lshr<mode>3_imm(operands[0], operands[1], operands[2]));
2085 operands[3] = gen_reg_rtx (<MODE>mode);
2086 operands[4] = gen_reg_rtx (SImode);
2087 operands[5] = gen_reg_rtx (SImode);")
2089 (define_insn_and_split "lshr<mode>3_imm"
2090 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2091 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2092 (match_operand:SI 2 "immediate_operand" "O,P")))]
2095 rotqmbyi\t%0,%1,%N2/8
2096 rotqmbii\t%0,%1,%N2"
2097 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2098 [(set (match_dup:DTI 0)
2099 (lshiftrt:DTI (match_dup:DTI 1)
2101 (set (match_dup:DTI 0)
2102 (lshiftrt:DTI (match_dup:DTI 0)
2105 HOST_WIDE_INT val = INTVAL(operands[2]);
2106 operands[4] = GEN_INT (val&7);
2107 operands[5] = GEN_INT (val&0x78);
2109 [(set_attr "type" "shuf,shuf")])
2111 (define_insn_and_split "lshr<mode>3_reg"
2112 [(set (match_operand:DTI 0 "spu_reg_operand" "=r")
2113 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r")
2114 (match_operand:SI 2 "spu_reg_operand" "r")))
2115 (clobber (match_operand:DTI 3 "spu_reg_operand" "=&r"))
2116 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
2117 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))]
2121 [(set (match_dup:DTI 3)
2122 (lshiftrt:DTI (match_dup:DTI 1)
2123 (and:SI (neg:SI (match_dup:SI 4))
2125 (set (match_dup:DTI 0)
2126 (lshiftrt:DTI (match_dup:DTI 3)
2127 (and:SI (neg:SI (match_dup:SI 5))
2130 emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2]));
2131 emit_insn(gen_subsi3(operands[5], GEN_INT(7), operands[2]));
2134 (define_insn "rotqmbybi_<mode>"
2135 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2136 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2137 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2142 rotqmbyi\t%0,%1,%2/8"
2143 [(set_attr "type" "shuf")])
2145 (define_insn "rotqmbi_<mode>"
2146 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2147 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2148 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2154 [(set_attr "type" "shuf")])
2156 (define_insn "rotqmby_<mode>"
2157 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2158 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2159 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2165 [(set_attr "type" "shuf")])
2170 (define_insn_and_split "ashr<mode>3"
2171 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2172 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2173 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
2174 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2178 rotma<bh>i\t%0,%1,%N2"
2179 "reload_completed && GET_CODE (operands[2]) == REG"
2180 [(set (match_dup:VHSI 3)
2181 (neg:VHSI (match_dup:VHSI 2)))
2182 (set (match_dup:VHSI 0)
2183 (ashiftrt:VHSI (match_dup:VHSI 1)
2184 (neg:VHSI (match_dup:VHSI 3))))]
2186 [(set_attr "type" "*,fx3")])
2189 (define_insn "rotma_<mode>"
2190 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2191 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2192 (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
2196 rotma<bh>i\t%0,%1,%2"
2197 [(set_attr "type" "fx3")])
2199 (define_insn_and_split "ashrdi3"
2200 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2201 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2202 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2203 (clobber (match_scratch:TI 3 "=&r,&r"))
2204 (clobber (match_scratch:TI 4 "=&r,&r"))
2205 (clobber (match_scratch:SI 5 "=&r,&r"))]
2209 [(set (match_dup:DI 0)
2210 (ashiftrt:DI (match_dup:DI 1)
2213 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2214 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2215 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2216 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2217 rtx op2 = operands[2];
2218 rtx op3 = operands[3];
2219 rtx op4 = operands[4];
2220 rtx op5 = operands[5];
2222 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2224 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2225 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2226 emit_insn (gen_spu_fsm (op0v, op0s));
2228 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2230 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2231 HOST_WIDE_INT val = INTVAL (op2);
2232 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2233 emit_insn (gen_spu_xswd (op0d, op0v));
2235 emit_insn (gen_ashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2239 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2240 unsigned char arr[16] = {
2241 0xff, 0xff, 0xff, 0xff,
2242 0xff, 0xff, 0xff, 0xff,
2243 0x00, 0x00, 0x00, 0x00,
2244 0x00, 0x00, 0x00, 0x00
2247 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2248 emit_move_insn (op4, array_to_constant (TImode, arr));
2249 emit_insn (gen_spu_fsm (op3v, op5));
2251 if (GET_CODE (operands[2]) == REG)
2253 emit_insn (gen_selb (op4, op3, op1, op4));
2254 emit_insn (gen_negsi2 (op5, op2));
2255 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2256 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2260 HOST_WIDE_INT val = -INTVAL (op2);
2261 emit_insn (gen_selb (op0, op3, op1, op4));
2263 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2265 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2272 (define_expand "ashrti3"
2273 [(set (match_operand:TI 0 "spu_reg_operand" "")
2274 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "")
2275 (match_operand:SI 2 "spu_nonmem_operand" "")))]
2278 rtx sign_shift = gen_reg_rtx (SImode);
2279 rtx sign_mask = gen_reg_rtx (TImode);
2280 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2281 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2282 rtx t = gen_reg_rtx (TImode);
2283 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2284 emit_insn (gen_ashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2285 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2286 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2287 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2288 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2292 ;; fsm is used after rotam to replicate the sign across the whole register.
2293 (define_insn "fsm_ti"
2294 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2295 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2298 [(set_attr "type" "shuf")])
2303 (define_insn "rotl<mode>3"
2304 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2305 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2306 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
2311 [(set_attr "type" "fx3")])
2313 (define_insn "rotlti3"
2314 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2315 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2316 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2319 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2322 rotqbyi\t%0,%1,%2/8\;rotqbii\t%0,%0,%2%%8"
2323 [(set_attr "length" "8,4,4,8")
2324 (set_attr "type" "multi1,shuf,shuf,multi1")])
2326 (define_insn "rotqbybi_ti"
2327 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2328 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2329 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2334 rotqbyi\t%0,%1,%2/8"
2335 [(set_attr "type" "shuf,shuf")])
2337 (define_insn "rotqby_ti"
2338 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2339 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2340 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2346 [(set_attr "type" "shuf,shuf")])
2348 (define_insn "rotqbi_ti"
2349 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2350 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2351 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2356 rotqbii\t%0,%1,%2%%8"
2357 [(set_attr "type" "shuf,shuf")])
2360 ;; struct extract/insert
2361 ;; We have to handle mem's because GCC will generate invalid SUBREG's
2362 ;; if it handles them. We generate better code anyway.
2364 (define_expand "extv"
2365 [(set (match_operand 0 "register_operand" "")
2366 (sign_extract (match_operand 1 "register_operand" "")
2367 (match_operand:SI 2 "const_int_operand" "")
2368 (match_operand:SI 3 "const_int_operand" "")))]
2370 { spu_expand_extv(operands, 0); DONE; })
2372 (define_expand "extzv"
2373 [(set (match_operand 0 "register_operand" "")
2374 (zero_extract (match_operand 1 "register_operand" "")
2375 (match_operand:SI 2 "const_int_operand" "")
2376 (match_operand:SI 3 "const_int_operand" "")))]
2378 { spu_expand_extv(operands, 1); DONE; })
2380 (define_expand "insv"
2381 [(set (zero_extract (match_operand 0 "register_operand" "")
2382 (match_operand:SI 1 "const_int_operand" "")
2383 (match_operand:SI 2 "const_int_operand" ""))
2384 (match_operand 3 "nonmemory_operand" ""))]
2386 { spu_expand_insv(operands); DONE; })
2389 ;; String/block move insn.
2390 ;; Argument 0 is the destination
2391 ;; Argument 1 is the source
2392 ;; Argument 2 is the length
2393 ;; Argument 3 is the alignment
2395 (define_expand "movstrsi"
2396 [(parallel [(set (match_operand:BLK 0 "" "")
2397 (match_operand:BLK 1 "" ""))
2398 (use (match_operand:SI 2 "" ""))
2399 (use (match_operand:SI 3 "" ""))])]
2403 if (spu_expand_block_move (operands))
2412 (define_insn "indirect_jump"
2413 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2416 [(set_attr "type" "br")])
2420 (label_ref (match_operand 0 "" "")))]
2423 [(set_attr "type" "br")])
2428 ;; This will be used for leaf functions, that don't save any regs and
2429 ;; don't have locals on stack, maybe... that is for functions that
2430 ;; don't change $sp and don't need to save $lr.
2431 (define_expand "return"
2436 ;; used in spu_expand_epilogue to generate return from a function and
2437 ;; explicitly set use of $lr.
2439 (define_insn "_return"
2443 [(set_attr "type" "br")])
2449 (define_insn "ceq_<mode>"
2450 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2451 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2452 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2456 ceq<bh>i\t%0,%1,%2")
2458 (define_insn_and_split "ceq_di"
2459 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2460 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2461 (match_operand:DI 2 "spu_reg_operand" "r")))]
2465 [(set (match_dup:SI 0)
2466 (eq:SI (match_dup:DI 1)
2469 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2470 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2471 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2472 emit_insn (gen_ceq_v4si (op0, op1, op2));
2473 emit_insn (gen_spu_gb (op0, op0));
2474 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2479 ;; We provide the TI compares for completeness and because some parts of
2480 ;; gcc/libgcc use them, even though user code might never see it.
2481 (define_insn "ceq_ti"
2482 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2483 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2484 (match_operand:TI 2 "spu_reg_operand" "r")))]
2486 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2487 [(set_attr "type" "multi0")
2488 (set_attr "length" "12")])
2490 (define_insn "ceq_<mode>"
2491 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2492 (eq:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
2493 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2497 (define_insn "cmeq_<mode>"
2498 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2499 (eq:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2500 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2504 (define_insn "ceq_vec"
2505 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2506 (eq:SI (match_operand 1 "spu_reg_operand" "r")
2507 (match_operand 2 "spu_reg_operand" "r")))]
2508 "VECTOR_MODE_P(GET_MODE(operands[1]))
2509 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2510 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2511 [(set_attr "length" "12")])
2516 (define_insn "cgt_<mode>"
2517 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2518 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2519 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2523 cgt<bh>i\t%0,%1,%2")
2525 (define_insn "cgt_di_m1"
2526 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2527 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2532 (define_insn_and_split "cgt_di"
2533 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2534 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2535 (match_operand:DI 2 "spu_reg_operand" "r")))
2536 (clobber (match_scratch:V4SI 3 "=&r"))
2537 (clobber (match_scratch:V4SI 4 "=&r"))
2538 (clobber (match_scratch:V4SI 5 "=&r"))]
2542 [(set (match_dup:SI 0)
2543 (gt:SI (match_dup:DI 1)
2546 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2547 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2548 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2549 rtx op3 = operands[3];
2550 rtx op4 = operands[4];
2551 rtx op5 = operands[5];
2552 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
2553 emit_insn (gen_clgt_v4si (op3, op1, op2));
2554 emit_insn (gen_ceq_v4si (op4, op1, op2));
2555 emit_insn (gen_cgt_v4si (op5, op1, op2));
2556 emit_insn (gen_spu_xswd (op3d, op3));
2557 emit_insn (gen_selb (op0, op5, op3, op4));
2561 (define_insn "cgt_ti"
2562 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2563 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
2564 (match_operand:TI 2 "spu_reg_operand" "r")))
2565 (clobber (match_scratch:V4SI 3 "=&r"))
2566 (clobber (match_scratch:V4SI 4 "=&r"))
2567 (clobber (match_scratch:V4SI 5 "=&r"))]
2573 selb\t%0,%4,%0,%3\;\
2575 selb\t%0,%4,%0,%3\;\
2578 [(set_attr "type" "multi0")
2579 (set_attr "length" "36")])
2581 (define_insn "cgt_<mode>"
2582 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2583 (gt:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
2584 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2588 (define_insn "cmgt_<mode>"
2589 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2590 (gt:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2591 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2598 (define_insn "clgt_<mode>"
2599 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2600 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2601 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2605 clgt<bh>i\t%0,%1,%2")
2607 (define_insn_and_split "clgt_di"
2608 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2609 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
2610 (match_operand:DI 2 "spu_reg_operand" "r")))
2611 (clobber (match_scratch:V4SI 3 "=&r"))
2612 (clobber (match_scratch:V4SI 4 "=&r"))
2613 (clobber (match_scratch:V4SI 5 "=&r"))]
2617 [(set (match_dup:SI 0)
2618 (gtu:SI (match_dup:DI 1)
2621 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2622 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2623 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2624 rtx op3 = operands[3];
2625 rtx op4 = operands[4];
2626 rtx op5 = operands[5];
2627 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
2628 emit_insn (gen_clgt_v4si (op3, op1, op2));
2629 emit_insn (gen_ceq_v4si (op4, op1, op2));
2630 emit_insn (gen_spu_xswd (op5d, op3));
2631 emit_insn (gen_selb (op0, op3, op5, op4));
2635 (define_insn "clgt_ti"
2636 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2637 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
2638 (match_operand:TI 2 "spu_reg_operand" "r")))
2639 (clobber (match_scratch:V4SI 3 "=&r"))
2640 (clobber (match_scratch:V4SI 4 "=&r"))]
2645 selb\t%0,%4,%0,%3\;\
2647 selb\t%0,%4,%0,%3\;\
2650 [(set_attr "type" "multi0")
2651 (set_attr "length" "32")])
2658 (if_then_else (match_operator 1 "branch_comparison_operator"
2660 "spu_reg_operand" "r")
2662 (label_ref (match_operand 0 "" ""))
2666 [(set_attr "type" "br")])
2670 (if_then_else (match_operator 0 "branch_comparison_operator"
2672 "spu_reg_operand" "r")
2678 [(set_attr "type" "br")])
2682 (if_then_else (match_operator 1 "branch_comparison_operator"
2684 "spu_reg_operand" "r")
2687 (label_ref (match_operand 0 "" ""))))]
2690 [(set_attr "type" "br")])
2694 (if_then_else (match_operator 0 "branch_comparison_operator"
2696 "spu_reg_operand" "r")
2702 [(set_attr "type" "br")])
2705 ;; Compare insns are next. Note that the spu has two types of compares,
2706 ;; signed & unsigned, and one type of branch.
2708 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
2709 ;; insns, and branches. We store the operands of compares until we see
2712 (define_expand "cmp<mode>"
2714 (compare (match_operand:VQHSI 0 "spu_reg_operand" "")
2715 (match_operand:VQHSI 1 "spu_nonmem_operand" "")))]
2718 spu_compare_op0 = operands[0];
2719 spu_compare_op1 = operands[1];
2723 (define_expand "cmp<mode>"
2725 (compare (match_operand:DTI 0 "spu_reg_operand" "")
2726 (match_operand:DTI 1 "spu_reg_operand" "")))]
2729 spu_compare_op0 = operands[0];
2730 spu_compare_op1 = operands[1];
2734 (define_expand "cmp<mode>"
2736 (compare (match_operand:VSF 0 "spu_reg_operand" "")
2737 (match_operand:VSF 1 "spu_reg_operand" "")))]
2740 spu_compare_op0 = operands[0];
2741 spu_compare_op1 = operands[1];
2746 ;; branch on condition
2748 (define_expand "beq"
2749 [(use (match_operand 0 "" ""))]
2751 { spu_emit_branch_or_set (0, EQ, operands); DONE; })
2753 (define_expand "bne"
2754 [(use (match_operand 0 "" ""))]
2756 { spu_emit_branch_or_set (0, NE, operands); DONE; })
2758 (define_expand "bge"
2759 [(use (match_operand 0 "" ""))]
2761 { spu_emit_branch_or_set (0, GE, operands); DONE; })
2763 (define_expand "bgt"
2764 [(use (match_operand 0 "" ""))]
2766 { spu_emit_branch_or_set (0, GT, operands); DONE; })
2768 (define_expand "ble"
2769 [(use (match_operand 0 "" ""))]
2771 { spu_emit_branch_or_set (0, LE, operands); DONE; })
2773 (define_expand "blt"
2774 [(use (match_operand 0 "" ""))]
2776 { spu_emit_branch_or_set (0, LT, operands); DONE; })
2778 (define_expand "bgeu"
2779 [(use (match_operand 0 "" ""))]
2781 { spu_emit_branch_or_set (0, GEU, operands); DONE; })
2783 (define_expand "bgtu"
2784 [(use (match_operand 0 "" ""))]
2786 { spu_emit_branch_or_set (0, GTU, operands); DONE; })
2788 (define_expand "bleu"
2789 [(use (match_operand 0 "" ""))]
2791 { spu_emit_branch_or_set (0, LEU, operands); DONE; })
2793 (define_expand "bltu"
2794 [(use (match_operand 0 "" ""))]
2796 { spu_emit_branch_or_set (0, LTU, operands); DONE; })
2801 (define_expand "seq"
2802 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2804 { spu_emit_branch_or_set (1, EQ, operands); DONE; })
2806 (define_expand "sne"
2807 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2809 { spu_emit_branch_or_set (1, NE, operands); DONE; })
2811 (define_expand "sgt"
2812 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2814 { spu_emit_branch_or_set (1, GT, operands); DONE; })
2816 (define_expand "slt"
2817 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2819 { spu_emit_branch_or_set (1, LT, operands); DONE; })
2821 (define_expand "sge"
2822 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2824 { spu_emit_branch_or_set (1, GE, operands); DONE; })
2826 (define_expand "sle"
2827 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2829 { spu_emit_branch_or_set (1, LE, operands); DONE; })
2831 (define_expand "sgtu"
2832 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2834 { spu_emit_branch_or_set (1, GTU, operands); DONE; })
2836 (define_expand "sltu"
2837 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2839 { spu_emit_branch_or_set (1, LTU, operands); DONE; })
2841 (define_expand "sgeu"
2842 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2844 { spu_emit_branch_or_set (1, GEU, operands); DONE; })
2846 (define_expand "sleu"
2847 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2849 { spu_emit_branch_or_set (1, LEU, operands); DONE; })
2854 ;; Define this first one so HAVE_conditional_move is defined.
2855 (define_insn "movcc_dummy"
2856 [(set (match_operand 0 "" "")
2857 (if_then_else (match_operand 1 "" "")
2858 (match_operand 2 "" "")
2859 (match_operand 3 "" "")))]
2863 (define_expand "mov<mode>cc"
2864 [(set (match_operand:ALL 0 "spu_reg_operand" "")
2865 (if_then_else:ALL (match_operand 1 "comparison_operator" "")
2866 (match_operand:ALL 2 "spu_reg_operand" "")
2867 (match_operand:ALL 3 "spu_reg_operand" "")))]
2870 spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
2874 ;; This pattern is used when the result of a compare is not large
2875 ;; enough to use in a selb when expanding conditional moves.
2876 (define_expand "extend_compare"
2877 [(set (match_operand 0 "spu_reg_operand" "=r")
2878 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
2881 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2882 gen_rtx_UNSPEC (GET_MODE (operands[0]),
2883 gen_rtvec (1, operands[1]),
2884 UNSPEC_EXTEND_CMP)));
2888 (define_insn "extend_compare<mode>"
2889 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2890 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
2893 [(set_attr "type" "shuf")])
2898 ;; operand 0 is index
2899 ;; operand 1 is the minimum bound
2900 ;; operand 2 is the maximum bound - minimum bound + 1
2901 ;; operand 3 is CODE_LABEL for the table;
2902 ;; operand 4 is the CODE_LABEL to go to if index out of range.
2903 (define_expand "casesi"
2904 [(match_operand:SI 0 "spu_reg_operand" "")
2905 (match_operand:SI 1 "immediate_operand" "")
2906 (match_operand:SI 2 "immediate_operand" "")
2907 (match_operand 3 "" "")
2908 (match_operand 4 "" "")]
2911 rtx table = gen_reg_rtx (SImode);
2912 rtx index = gen_reg_rtx (SImode);
2913 rtx sindex = gen_reg_rtx (SImode);
2914 rtx addr = gen_reg_rtx (Pmode);
2916 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
2918 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
2919 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
2920 emit_move_insn (addr, gen_rtx_MEM (SImode,
2921 gen_rtx_PLUS (SImode, table, sindex)));
2923 emit_insn (gen_addsi3 (addr, addr, table));
2925 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
2926 emit_jump_insn (gen_tablejump (addr, operands[3]));
2930 (define_insn "tablejump"
2931 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
2932 (use (label_ref (match_operand 1 "" "")))]
2935 [(set_attr "type" "br")])
2940 ;; Note that operand 1 is total size of args, in bytes,
2941 ;; and what the call insn wants is the number of words.
2942 (define_expand "sibcall"
2944 [(call (match_operand:QI 0 "call_operand" "")
2945 (match_operand:QI 1 "" ""))
2949 if (! call_operand (operands[0], QImode))
2950 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2953 (define_insn "_sibcall"
2955 [(call (match_operand:QI 0 "call_operand" "R,S")
2956 (match_operand:QI 1 "" "i,i"))
2958 "SIBLING_CALL_P(insn)"
2962 [(set_attr "type" "br,br")])
2964 (define_expand "sibcall_value"
2966 [(set (match_operand 0 "" "")
2967 (call (match_operand:QI 1 "call_operand" "")
2968 (match_operand:QI 2 "" "")))
2972 if (! call_operand (operands[1], QImode))
2973 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2976 (define_insn "_sibcall_value"
2978 [(set (match_operand 0 "" "")
2979 (call (match_operand:QI 1 "call_operand" "R,S")
2980 (match_operand:QI 2 "" "i,i")))
2982 "SIBLING_CALL_P(insn)"
2986 [(set_attr "type" "br,br")])
2988 ;; Note that operand 1 is total size of args, in bytes,
2989 ;; and what the call insn wants is the number of words.
2990 (define_expand "call"
2992 [(call (match_operand:QI 0 "call_operand" "")
2993 (match_operand:QI 1 "" ""))
2994 (clobber (reg:SI 0))
2995 (clobber (reg:SI 130))])]
2998 if (! call_operand (operands[0], QImode))
2999 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3002 (define_insn "_call"
3004 [(call (match_operand:QI 0 "call_operand" "R,S,T")
3005 (match_operand:QI 1 "" "i,i,i"))
3006 (clobber (reg:SI 0))
3007 (clobber (reg:SI 130))])]
3013 [(set_attr "type" "br")])
3015 (define_expand "call_value"
3017 [(set (match_operand 0 "" "")
3018 (call (match_operand:QI 1 "call_operand" "")
3019 (match_operand:QI 2 "" "")))
3020 (clobber (reg:SI 0))
3021 (clobber (reg:SI 130))])]
3024 if (! call_operand (operands[1], QImode))
3025 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3028 (define_insn "_call_value"
3030 [(set (match_operand 0 "" "")
3031 (call (match_operand:QI 1 "call_operand" "R,S,T")
3032 (match_operand:QI 2 "" "i,i,i")))
3033 (clobber (reg:SI 0))
3034 (clobber (reg:SI 130))])]
3040 [(set_attr "type" "br")])
3042 (define_expand "untyped_call"
3043 [(parallel [(call (match_operand 0 "" "")
3045 (match_operand 1 "" "")
3046 (match_operand 2 "" "")])]
3050 rtx reg = gen_rtx_REG (TImode, 3);
3052 /* We need to use call_value so the return value registers don't get
3054 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
3056 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3058 rtx set = XVECEXP (operands[2], 0, i);
3059 emit_move_insn (SET_DEST (set), SET_SRC (set));
3062 /* The optimizer does not know that the call sets the function value
3063 registers we stored in the result block. We avoid problems by
3064 claiming that all hard registers are used and clobbered at this
3066 emit_insn (gen_blockage ());
3072 ;; Patterns used for splitting and combining.
3075 ;; Function prologue and epilogue.
3077 (define_expand "prologue"
3080 { spu_expand_prologue (); DONE; })
3082 ;; "blockage" is only emited in epilogue. This is what it took to
3083 ;; make "basic block reordering" work with the insns sequence
3084 ;; generated by the spu_expand_epilogue (taken from mips.md)
3086 (define_insn "blockage"
3087 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
3090 [(set_attr "length" "0")])
3092 (define_expand "epilogue"
3095 { spu_expand_epilogue (false); DONE; })
3097 (define_expand "sibcall_epilogue"
3100 { spu_expand_epilogue (true); DONE; })
3103 ;; stack manipulations
3105 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
3106 ;; We move the back-chain and decrement the stack pointer.
3107 (define_expand "allocate_stack"
3108 [(set (match_operand 0 "spu_reg_operand" "")
3109 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
3111 (minus (reg 1) (match_dup 1)))]
3113 "spu_allocate_stack (operands[0], operands[1]); DONE;")
3115 ;; These patterns say how to save and restore the stack pointer. We need not
3116 ;; save the stack pointer at function or block level since we are careful to
3117 ;; preserve the backchain. Doing nothing at block level means the stack space
3118 ;; is allocated until the end of the function. This is currently safe to do
3119 ;; because gcc uses the frame pointer for the whole function, so the worst that
3120 ;; happens is wasted stack space. That could be bad if a VLA is declared in a
3121 ;; loop, because new space will be allocated every iteration, but users can
3122 ;; work around that case. Ideally we could detect when we are in a loop and
3123 ;; generate the more complicated code in that case.
3125 ;; For nonlocal gotos, we must save both the stack pointer and its
3126 ;; backchain and restore both. Note that in the nonlocal case, the
3127 ;; save area is a memory location.
3129 (define_expand "save_stack_function"
3130 [(match_operand 0 "general_operand" "")
3131 (match_operand 1 "general_operand" "")]
3135 (define_expand "restore_stack_function"
3136 [(match_operand 0 "general_operand" "")
3137 (match_operand 1 "general_operand" "")]
3141 (define_expand "save_stack_block"
3142 [(match_operand 0 "general_operand" "")
3143 (match_operand 1 "general_operand" "")]
3147 (define_expand "restore_stack_block"
3148 [(use (match_operand 0 "spu_reg_operand" ""))
3149 (set (match_dup 2) (match_dup 3))
3150 (set (match_dup 0) (match_operand 1 "spu_reg_operand" ""))
3151 (set (match_dup 3) (match_dup 2))]
3155 (define_expand "save_stack_nonlocal"
3156 [(match_operand 0 "memory_operand" "")
3157 (match_operand 1 "spu_reg_operand" "")]
3161 rtx temp = gen_reg_rtx (Pmode);
3163 /* Copy the backchain to the first word, sp to the second. We need to
3164 save the back chain because __builtin_apply appears to clobber it. */
3165 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
3166 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
3167 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
3171 (define_expand "restore_stack_nonlocal"
3172 [(match_operand 0 "spu_reg_operand" "")
3173 (match_operand 1 "memory_operand" "")]
3177 spu_restore_stack_nonlocal(operands[0], operands[1]);
3184 ;; Vector initialization
3185 (define_expand "vec_init<mode>"
3186 [(match_operand:V 0 "register_operand" "")
3187 (match_operand 1 "" "")]
3190 spu_expand_vector_init (operands[0], operands[1]);
3194 (define_expand "vec_set<mode>"
3195 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
3196 (set (match_dup:TI 3)
3197 (unspec:TI [(match_dup:SI 4)
3199 (match_dup:SI 6)] UNSPEC_CPAT))
3200 (set (match_operand:V 0 "spu_reg_operand" "")
3201 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
3203 (match_dup:TI 3)] UNSPEC_SHUFB))]
3206 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
3207 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
3208 operands[3] = gen_reg_rtx (TImode);
3209 operands[4] = stack_pointer_rtx;
3210 operands[5] = offset;
3211 operands[6] = GEN_INT (size);
3214 (define_expand "vec_extract<mode>"
3215 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
3216 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
3217 (parallel [(match_operand 2 "const_int_operand" "i")])))]
3220 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
3222 emit_insn (gen_spu_convert (operands[0], operands[1]));
3227 (define_insn "_vec_extract<mode>"
3228 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
3229 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
3230 (parallel [(match_operand 2 "const_int_operand" "i")])))]
3232 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
3233 [(set_attr "type" "shuf")])
3238 (define_expand "shufb"
3239 [(set (match_operand 0 "spu_reg_operand" "")
3240 (unspec [(match_operand 1 "spu_reg_operand" "")
3241 (match_operand 2 "spu_reg_operand" "")
3242 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
3245 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
3246 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
3251 (define_insn "_shufb"
3252 [(set (match_operand 0 "spu_reg_operand" "=r")
3253 (unspec [(match_operand 1 "spu_reg_operand" "r")
3254 (match_operand 2 "spu_reg_operand" "r")
3255 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
3257 "shufb\t%0,%1,%2,%3"
3258 [(set_attr "type" "shuf")])
3261 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
3264 [(set_attr "type" "nop")])
3267 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
3270 [(set_attr "type" "nop")])
3273 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
3276 [(set_attr "type" "lnop")])
3278 (define_insn "iprefetch"
3279 [(unspec [(const_int 0)] UNSPEC_IPREFETCH)]
3282 [(set_attr "type" "iprefetch")])
3286 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s,s,s")
3287 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
3288 (unspec [(const_int 0)] UNSPEC_HBR)]
3294 [(set_attr "type" "hbr")])
3297 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
3298 (clobber (mem:BLK (scratch)))]
3301 [(set_attr "type" "br")])
3303 (define_insn "syncc"
3304 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
3305 (clobber (mem:BLK (scratch)))]
3308 [(set_attr "type" "br")])
3310 (define_insn "dsync"
3311 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
3312 (clobber (mem:BLK (scratch)))]
3315 [(set_attr "type" "br")])
3318 ;; convert between any two modes, avoiding any GCC assumptions
3319 (define_expand "spu_convert"
3320 [(set (match_operand 0 "spu_reg_operand" "")
3321 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
3324 rtx c = gen__spu_convert (operands[0], operands[1]);
3325 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
3330 (define_insn "_spu_convert"
3331 [(set (match_operand 0 "spu_reg_operand" "=r")
3332 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
3335 [(set_attr "type" "convert")
3336 (set_attr "length" "0")])
3339 [(set (match_operand 0 "spu_reg_operand")
3340 (unspec [(match_operand 1 "spu_reg_operand")] UNSPEC_CONVERT))]
3342 [(use (const_int 0))]
3347 (include "spu-builtins.md")
3350 (define_expand "smaxv4sf3"
3351 [(set (match_operand:V4SF 0 "register_operand" "=r")
3352 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
3353 (match_operand:V4SF 2 "register_operand" "r")))]
3357 rtx mask = gen_reg_rtx (V4SImode);
3359 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
3360 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
3364 (define_expand "sminv4sf3"
3365 [(set (match_operand:V4SF 0 "register_operand" "=r")
3366 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
3367 (match_operand:V4SF 2 "register_operand" "r")))]
3371 rtx mask = gen_reg_rtx (V4SImode);
3373 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
3374 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));