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:SI 0 "spu_reg_operand" "=r")
242 (match_operand:SI 1 "immediate_operand" "s"))]
244 "(flag_pic || TARGET_LARGE_MEM
245 || (GET_CODE (operands[1]) == CONST
246 && !legitimate_const (operands[1], 0)))
247 && (reload_in_progress || reload_completed)
248 && (GET_CODE (operands[1]) == CONST
249 || GET_CODE (operands[1]) == SYMBOL_REF
250 || GET_CODE (operands[1]) == LABEL_REF)"
252 [(set (match_dup:SI 0)
254 (use (const_int 0))])
255 (set (match_dup:SI 0)
256 (plus:SI (match_dup:SI 0)
259 spu_split_address(operands);
264 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
265 (match_operand:SI 1 "immediate_operand" "s"))
270 ;; Whenever a function generates the 'pic' pattern above we need to
271 ;; load the pic_offset_table register.
272 ;; GCC doesn't deal well with labels in the middle of a block so we
273 ;; hardcode the offsets in the asm here.
274 (define_insn "load_pic_offset"
275 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
276 (unspec:SI [(const_int 0)] 0))
277 (set (match_operand:SI 1 "spu_reg_operand" "=r")
278 (unspec:SI [(const_int 0)] 0))]
280 "ila\t%1,.+8\;brsl\t%0,4"
281 [(set_attr "length" "8")
282 (set_attr "type" "multi0")])
287 (define_insn "_mov<mode>"
288 [(set (match_operand:MOV 0 "spu_nonimm_operand" "=r,r,r,r,m")
289 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,m,r"))]
290 "spu_valid_move (operands)"
297 [(set_attr "type" "fx2,fx2,shuf,load,store")])
300 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
301 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
306 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
307 (lo_sum:SI (match_operand:SI 1 "spu_reg_operand" "0")
308 (match_operand:SI 2 "immediate_operand" "i")))]
312 (define_insn "_movdi"
313 [(set (match_operand:DI 0 "spu_nonimm_operand" "=r,r,r,r,m")
314 (match_operand:DI 1 "spu_mov_operand" "r,a,f,m,r"))]
315 "spu_valid_move (operands)"
322 [(set_attr "type" "fx2,fx2,shuf,load,store")])
324 (define_insn "_movti"
325 [(set (match_operand:TI 0 "spu_nonimm_operand" "=r,r,r,r,m")
326 (match_operand:TI 1 "spu_mov_operand" "r,U,f,m,r"))]
327 "spu_valid_move (operands)"
334 [(set_attr "type" "fx2,fx2,shuf,load,store")])
336 (define_insn_and_split "load"
337 [(set (match_operand 0 "spu_reg_operand" "=r")
338 (match_operand 1 "memory_operand" "m"))
339 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
340 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))]
341 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
346 { spu_split_load(operands); DONE; })
348 (define_insn_and_split "store"
349 [(set (match_operand 0 "memory_operand" "=m")
350 (match_operand 1 "spu_reg_operand" "r"))
351 (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
352 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
353 "GET_MODE(operands[0]) == GET_MODE(operands[1])"
358 { spu_split_store(operands); DONE; })
360 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
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))]
370 [(set_attr "type" "shuf")])
375 (define_insn "extendqihi2"
376 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
377 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
381 (define_insn "extendhisi2"
382 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
383 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
387 (define_expand "extendsidi2"
388 [(set (match_dup:DI 2)
389 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
390 (set (match_operand:DI 0 "spu_reg_operand" "")
391 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
392 (parallel [(const_int 1)]))))]
395 operands[2] = gen_reg_rtx (DImode);
396 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
400 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
403 (match_operand:V2SI 1 "spu_reg_operand" "r")
404 (parallel [(const_int 1) ]))))]
408 (define_expand "extendqiti2"
409 [(set (match_operand:TI 0 "register_operand" "")
410 (sign_extend:TI (match_operand:QI 1 "register_operand" "")))]
412 "spu_expand_sign_extend(operands);
415 (define_expand "extendhiti2"
416 [(set (match_operand:TI 0 "register_operand" "")
417 (sign_extend:TI (match_operand:HI 1 "register_operand" "")))]
419 "spu_expand_sign_extend(operands);
422 (define_expand "extendsiti2"
423 [(set (match_operand:TI 0 "register_operand" "")
424 (sign_extend:TI (match_operand:SI 1 "register_operand" "")))]
426 "spu_expand_sign_extend(operands);
429 (define_expand "extendditi2"
430 [(set (match_operand:TI 0 "register_operand" "")
431 (sign_extend:TI (match_operand:DI 1 "register_operand" "")))]
433 "spu_expand_sign_extend(operands);
439 (define_insn "zero_extendqihi2"
440 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
441 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
443 "andi\t%0,%1,0x00ff")
445 (define_insn "zero_extendqisi2"
446 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
447 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
449 "andi\t%0,%1,0x00ff")
451 (define_expand "zero_extendhisi2"
452 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
453 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
454 (clobber (match_scratch:SI 2 "=&r"))]
457 rtx mask = gen_reg_rtx (SImode);
458 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
459 emit_move_insn (mask, GEN_INT (0xffff));
460 emit_insn (gen_andsi3(operands[0], op1, mask));
464 (define_insn "zero_extendsidi2"
465 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
466 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
469 [(set_attr "type" "shuf")])
471 (define_insn "zero_extendsiti2"
472 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
473 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
475 "rotqmbyi\t%0,%1,-12"
476 [(set_attr "type" "shuf")])
478 (define_insn "zero_extendditi2"
479 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
480 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
483 [(set_attr "type" "shuf")])
488 (define_insn "truncdiqi2"
489 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
490 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
493 [(set_attr "type" "shuf")])
495 (define_insn "truncdihi2"
496 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
497 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
500 [(set_attr "type" "shuf")])
502 (define_insn "truncdisi2"
503 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
504 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
507 [(set_attr "type" "shuf")])
509 (define_insn "trunctiqi2"
510 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
511 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
514 [(set_attr "type" "shuf")])
516 (define_insn "trunctihi2"
517 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
518 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
521 [(set_attr "type" "shuf")])
523 (define_insn "trunctisi2"
524 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
525 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
528 [(set_attr "type" "shuf")])
530 (define_insn "trunctidi2"
531 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
532 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
535 [(set_attr "type" "shuf")])
540 (define_insn "floatsisf2"
541 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
542 (float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
545 [(set_attr "type" "fp7")])
547 (define_insn "floatv4siv4sf2"
548 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
549 (float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
552 [(set_attr "type" "fp7")])
554 (define_insn "fix_truncsfsi2"
555 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
556 (fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
559 [(set_attr "type" "fp7")])
561 (define_insn "fix_truncv4sfv4si2"
562 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
563 (fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
566 [(set_attr "type" "fp7")])
568 (define_insn "floatunssisf2"
569 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
570 (unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
573 [(set_attr "type" "fp7")])
575 (define_insn "floatunsv4siv4sf2"
576 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
577 (unsigned_float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
580 [(set_attr "type" "fp7")])
582 (define_insn "fixuns_truncsfsi2"
583 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
584 (unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
587 [(set_attr "type" "fp7")])
589 (define_insn "fixuns_truncv4sfv4si2"
590 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
591 (unsigned_fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
594 [(set_attr "type" "fp7")])
596 (define_insn "extendsfdf2"
597 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
598 (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))]
601 [(set_attr "type" "fpd")])
603 (define_insn "truncdfsf2"
604 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
605 (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))]
608 [(set_attr "type" "fpd")])
610 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
611 (define_expand "floatsidf2"
612 [(set (match_operand:DF 0 "register_operand" "")
613 (float:DF (match_operand:SI 1 "register_operand" "")))]
617 rtx c0 = gen_reg_rtx (SImode);
618 rtx c1 = gen_reg_rtx (DFmode);
619 rtx r0 = gen_reg_rtx (SImode);
620 rtx r1 = gen_reg_rtx (DFmode);
622 emit_move_insn (c0, GEN_INT (-0x80000000ll));
623 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
625 emit_insn (gen_xorsi3 (r0, operands[1], c0));
629 emit_library_call_value (ufloat_optab->handlers[DFmode][SImode].libfunc,
630 NULL_RTX, LCT_NORMAL, DFmode, 1, r0, SImode);
631 insns = get_insns ();
633 emit_libcall_block (insns, r1, value,
634 gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
636 emit_insn (gen_subdf3 (operands[0], r1, c1));
640 (define_expand "floatdidf2"
641 [(set (match_operand:DF 0 "register_operand" "")
642 (float:DF (match_operand:DI 1 "register_operand" "")))]
646 rtx c0 = gen_reg_rtx (DImode);
647 rtx r0 = gen_reg_rtx (DImode);
648 rtx r1 = gen_reg_rtx (DFmode);
649 rtx r2 = gen_reg_rtx (DImode);
650 rtx setneg = gen_reg_rtx (DImode);
651 rtx isneg = gen_reg_rtx (SImode);
652 rtx neg = gen_reg_rtx (DImode);
653 rtx mask = gen_reg_rtx (DImode);
655 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
657 emit_insn (gen_negdi2 (neg, operands[1]));
658 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
659 emit_insn (gen_extend_compare (mask, isneg));
660 emit_insn (gen_selb (r0, neg, operands[1], mask));
661 emit_insn (gen_andc_di (setneg, c0, mask));
666 emit_library_call_value (ufloat_optab->handlers[DFmode][DImode].libfunc,
667 NULL_RTX, LCT_NORMAL, DFmode, 1, r0, DImode);
668 insns = get_insns ();
670 emit_libcall_block (insns, r1, value,
671 gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
673 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
674 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
680 (define_expand "addv16qi3"
681 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
682 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
683 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
686 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
687 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
688 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
689 rtx rhs_and = gen_reg_rtx (V8HImode);
690 rtx hi_char = gen_reg_rtx (V8HImode);
691 rtx lo_char = gen_reg_rtx (V8HImode);
692 rtx mask = gen_reg_rtx (V8HImode);
694 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
695 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
696 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
697 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
698 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
702 (define_insn "add<mode>3"
703 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
704 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
705 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
711 (define_expand "add<mode>3"
712 [(set (match_dup:VDI 3)
713 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
714 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
715 (set (match_dup:VDI 5)
716 (unspec:VDI [(match_dup 3)
718 (match_dup:TI 4)] UNSPEC_SHUFB))
719 (set (match_operand:VDI 0 "spu_reg_operand" "")
720 (unspec:VDI [(match_dup 1)
722 (match_dup 5)] UNSPEC_ADDX))]
725 unsigned char pat[16] = {
726 0x04, 0x05, 0x06, 0x07,
727 0x80, 0x80, 0x80, 0x80,
728 0x0c, 0x0d, 0x0e, 0x0f,
729 0x80, 0x80, 0x80, 0x80
731 operands[3] = gen_reg_rtx (<MODE>mode);
732 operands[4] = gen_reg_rtx (TImode);
733 operands[5] = gen_reg_rtx (<MODE>mode);
734 emit_move_insn (operands[4], array_to_constant (TImode, pat));
737 (define_insn "cg_<mode>"
738 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
739 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
740 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
744 (define_insn "cgx_<mode>"
745 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
746 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
747 (match_operand 2 "spu_reg_operand" "r")
748 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
752 (define_insn "addx_<mode>"
753 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
754 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
755 (match_operand 2 "spu_reg_operand" "r")
756 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
761 ;; This is not the most efficient implementation of addti3.
762 ;; We include this here because 1) the compiler needs it to be
763 ;; defined as the word size is 128-bit and 2) sometimes gcc
764 ;; substitutes an add for a constant left-shift. 2) is unlikely
765 ;; because we also give addti3 a high cost. In case gcc does
766 ;; generate TImode add, here is the code to do it.
767 ;; operand 2 is a nonmemory because the compiler requires it.
768 (define_insn "addti3"
769 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
770 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
771 (match_operand:TI 2 "spu_nonmem_operand" "r")))
772 (clobber (match_scratch:TI 3 "=&r"))]
781 [(set_attr "type" "multi0")
782 (set_attr "length" "28")])
784 (define_insn "add<mode>3"
785 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
786 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
787 (match_operand:VSF 2 "spu_reg_operand" "r")))]
790 [(set_attr "type" "fp6")])
792 (define_insn "add<mode>3"
793 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
794 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
795 (match_operand:VDF 2 "spu_reg_operand" "r")))]
798 [(set_attr "type" "fpd")])
803 (define_expand "subv16qi3"
804 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
805 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
806 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
809 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
810 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
811 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
812 rtx rhs_and = gen_reg_rtx (V8HImode);
813 rtx hi_char = gen_reg_rtx (V8HImode);
814 rtx lo_char = gen_reg_rtx (V8HImode);
815 rtx mask = gen_reg_rtx (V8HImode);
817 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
818 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
819 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
820 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
821 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
825 (define_insn "sub<mode>3"
826 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
827 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
828 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
834 (define_expand "sub<mode>3"
835 [(set (match_dup:VDI 3)
836 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
837 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
838 (set (match_dup:VDI 5)
839 (unspec:VDI [(match_dup 3)
841 (match_dup:TI 4)] UNSPEC_SHUFB))
842 (set (match_operand:VDI 0 "spu_reg_operand" "")
843 (unspec:VDI [(match_dup 1)
845 (match_dup 5)] UNSPEC_SFX))]
848 unsigned char pat[16] = {
849 0x04, 0x05, 0x06, 0x07,
850 0xc0, 0xc0, 0xc0, 0xc0,
851 0x0c, 0x0d, 0x0e, 0x0f,
852 0xc0, 0xc0, 0xc0, 0xc0
854 operands[3] = gen_reg_rtx (<MODE>mode);
855 operands[4] = gen_reg_rtx (TImode);
856 operands[5] = gen_reg_rtx (<MODE>mode);
857 emit_move_insn (operands[4], array_to_constant (TImode, pat));
860 (define_insn "bg_<mode>"
861 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
862 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
863 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
867 (define_insn "bgx_<mode>"
868 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
869 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
870 (match_operand 2 "spu_reg_operand" "r")
871 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
875 (define_insn "sfx_<mode>"
876 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
877 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
878 (match_operand 2 "spu_reg_operand" "r")
879 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
883 (define_insn "subti3"
884 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
885 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
886 (match_operand:TI 2 "spu_reg_operand" "r")))
887 (clobber (match_scratch:TI 3 "=&r"))
888 (clobber (match_scratch:TI 4 "=&r"))
889 (clobber (match_scratch:TI 5 "=&r"))]
900 [(set_attr "type" "multi0")
901 (set_attr "length" "36")])
903 (define_insn "sub<mode>3"
904 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
905 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
906 (match_operand:VSF 2 "spu_reg_operand" "r")))]
909 [(set_attr "type" "fp6")])
911 (define_insn "sub<mode>3"
912 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
913 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
914 (match_operand:VDF 2 "spu_reg_operand" "r")))]
917 [(set_attr "type" "fpd")])
922 (define_expand "negv16qi2"
923 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
924 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
927 rtx zero = gen_reg_rtx (V16QImode);
928 emit_move_insn (zero, CONST0_RTX (V16QImode));
929 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
933 (define_insn "neg<mode>2"
934 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
935 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
939 (define_expand "negdi2"
940 [(set (match_operand:DI 0 "spu_reg_operand" "")
941 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
944 rtx zero = gen_reg_rtx(DImode);
945 emit_move_insn(zero, GEN_INT(0));
946 emit_insn(gen_subdi3(operands[0], zero, operands[1]));
950 (define_expand "negti2"
951 [(set (match_operand:TI 0 "spu_reg_operand" "")
952 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
955 rtx zero = gen_reg_rtx(TImode);
956 emit_move_insn(zero, GEN_INT(0));
957 emit_insn(gen_subti3(operands[0], zero, operands[1]));
961 (define_expand "neg<mode>2"
963 [(set (match_operand:VSF 0 "spu_reg_operand" "")
964 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
965 (use (match_dup 2))])]
967 "operands[2] = gen_reg_rtx (<f2i>mode);
968 emit_move_insn (operands[2], spu_const (<f2i>mode, -0x80000000ull));")
970 (define_expand "neg<mode>2"
972 [(set (match_operand:VDF 0 "spu_reg_operand" "")
973 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
974 (use (match_dup 2))])]
976 "operands[2] = gen_reg_rtx (<f2i>mode);
977 emit_move_insn (operands[2], spu_const (<f2i>mode, -0x8000000000000000ull));")
979 (define_insn_and_split "_neg<mode>2"
980 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
981 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
982 (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
986 [(set (match_dup:<f2i> 3)
987 (xor:<f2i> (match_dup:<f2i> 4)
988 (match_dup:<f2i> 2)))]
990 operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
991 operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
997 (define_expand "abs<mode>2"
999 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1000 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1001 (use (match_dup 2))])]
1003 "operands[2] = gen_reg_rtx (<f2i>mode);
1004 emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffull));")
1006 (define_expand "abs<mode>2"
1008 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1009 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1010 (use (match_dup 2))])]
1012 "operands[2] = gen_reg_rtx (<f2i>mode);
1013 emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffffffffffull));")
1015 (define_insn_and_split "_abs<mode>2"
1016 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1017 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1018 (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
1022 [(set (match_dup:<f2i> 3)
1023 (and:<f2i> (match_dup:<f2i> 4)
1024 (match_dup:<f2i> 2)))]
1026 operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
1027 operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
1033 (define_insn "mulhi3"
1034 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1035 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1036 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1041 [(set_attr "type" "fp7")])
1043 (define_expand "mulv8hi3"
1044 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1045 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1046 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1049 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1050 rtx low = gen_reg_rtx (V4SImode);
1051 rtx high = gen_reg_rtx (V4SImode);
1052 rtx shift = gen_reg_rtx (V4SImode);
1053 rtx mask = gen_reg_rtx (V4SImode);
1055 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1056 emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1057 emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1058 emit_insn (gen_ashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1059 emit_insn (gen_selb (result, shift, low, mask));
1063 (define_expand "mul<mode>3"
1065 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1066 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1067 (match_operand:VSI 2 "spu_reg_operand" "")))
1068 (clobber (match_dup:VSI 3))
1069 (clobber (match_dup:VSI 4))
1070 (clobber (match_dup:VSI 5))
1071 (clobber (match_dup:VSI 6))])]
1074 operands[3] = gen_reg_rtx(<MODE>mode);
1075 operands[4] = gen_reg_rtx(<MODE>mode);
1076 operands[5] = gen_reg_rtx(<MODE>mode);
1077 operands[6] = gen_reg_rtx(<MODE>mode);
1080 (define_insn_and_split "_mulsi3"
1081 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1082 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1083 (match_operand:SI 2 "spu_arith_operand" "rK")))
1084 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1085 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1086 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1087 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1091 [(set (match_dup:SI 0)
1092 (mult:SI (match_dup:SI 1)
1095 HOST_WIDE_INT val = 0;
1096 rtx a = operands[3];
1097 rtx b = operands[4];
1098 rtx c = operands[5];
1099 rtx d = operands[6];
1100 if (GET_CODE(operands[2]) == CONST_INT)
1102 val = INTVAL(operands[2]);
1103 emit_move_insn(d, operands[2]);
1106 if (val && (val & 0xffff) == 0)
1108 emit_insn(gen_mpyh_si(operands[0], operands[2], operands[1]));
1110 else if (val > 0 && val < 0x10000)
1112 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1113 emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
1114 emit_insn(gen_mpyu_si(c, operands[1], cst));
1115 emit_insn(gen_addsi3(operands[0], a, c));
1119 emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
1120 emit_insn(gen_mpyh_si(b, operands[2], operands[1]));
1121 emit_insn(gen_mpyu_si(c, operands[1], operands[2]));
1122 emit_insn(gen_addsi3(d, a, b));
1123 emit_insn(gen_addsi3(operands[0], d, c));
1128 (define_insn_and_split "_mulv4si3"
1129 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1130 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1131 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1132 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1133 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1134 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1135 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1139 [(set (match_dup:V4SI 0)
1140 (mult:V4SI (match_dup:V4SI 1)
1141 (match_dup:V4SI 2)))]
1143 rtx a = operands[3];
1144 rtx b = operands[4];
1145 rtx c = operands[5];
1146 rtx d = operands[6];
1147 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1148 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1149 emit_insn(gen_spu_mpyh(a, op1, op2));
1150 emit_insn(gen_spu_mpyh(b, op2, op1));
1151 emit_insn(gen_spu_mpyu(c, op1, op2));
1152 emit_insn(gen_addv4si3(d, a, b));
1153 emit_insn(gen_addv4si3(operands[0], d, c));
1157 (define_insn "mulhisi3"
1158 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1159 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1160 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1163 [(set_attr "type" "fp7")])
1165 (define_insn "mulhisi3_imm"
1166 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1167 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1168 (match_operand:SI 2 "immediate_operand" "K")))]
1171 [(set_attr "type" "fp7")])
1173 (define_insn "umulhisi3"
1174 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1175 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1176 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1179 [(set_attr "type" "fp7")])
1181 (define_insn "umulhisi3_imm"
1182 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1183 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1184 (and:SI (match_operand:SI 2 "immediate_operand" "K") (const_int 65535))))]
1187 [(set_attr "type" "fp7")])
1189 (define_insn "mpyu_si"
1190 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1191 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1193 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1194 (const_int 65535))))]
1199 [(set_attr "type" "fp7")])
1201 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1202 ;; It's faster to do the multiplies in parallel then add them. If we
1203 ;; merge a multiply and add it prevents the multiplies from happening in
1205 (define_insn "mpya_si"
1206 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1207 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1208 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1209 (match_operand:SI 3 "spu_reg_operand" "r")))]
1212 [(set_attr "type" "fp7")])
1214 (define_insn "mpyh_si"
1215 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1216 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1218 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1219 (const_int 65535))))]
1222 [(set_attr "type" "fp7")])
1224 (define_insn "mpys_si"
1225 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1227 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1228 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1232 [(set_attr "type" "fp7")])
1234 (define_insn "mpyhh_si"
1235 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1236 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1238 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1242 [(set_attr "type" "fp7")])
1244 (define_insn "mpyhhu_si"
1245 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1246 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1248 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1252 [(set_attr "type" "fp7")])
1254 (define_insn "mpyhha_si"
1255 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1256 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1258 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1260 (match_operand:SI 3 "spu_reg_operand" "0")))]
1263 [(set_attr "type" "fp7")])
1265 (define_insn "mul<mode>3"
1266 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1267 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1268 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1271 [(set_attr "type" "fp<d6>")])
1273 (define_insn "fma_<mode>"
1274 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1275 (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1276 (match_operand:VSF 2 "spu_reg_operand" "r"))
1277 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1280 [(set_attr "type" "fp6")])
1282 (define_insn "fnms_<mode>"
1283 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1284 (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1285 (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1286 (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1289 [(set_attr "type" "fp6")])
1291 (define_insn "fms_<mode>"
1292 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1293 (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1294 (match_operand:VSF 2 "spu_reg_operand" "r"))
1295 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1298 [(set_attr "type" "fp6")])
1300 (define_insn "fma_<mode>"
1301 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1302 (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1303 (match_operand:VDF 2 "spu_reg_operand" "r"))
1304 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1307 [(set_attr "type" "fpd")])
1309 (define_insn "fnma_<mode>"
1310 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1311 (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1312 (match_operand:VDF 2 "spu_reg_operand" "r"))
1313 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1316 [(set_attr "type" "fpd")])
1318 (define_insn "fnms_<mode>"
1319 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1320 (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1321 (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1322 (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1325 [(set_attr "type" "fpd")])
1327 (define_insn "fms_<mode>"
1328 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1329 (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1330 (match_operand:VDF 2 "spu_reg_operand" "r"))
1331 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1334 [(set_attr "type" "fpd")])
1337 ;; mul highpart, used for divide by constant optimizations.
1339 (define_expand "smulsi3_highpart"
1340 [(set (match_operand:SI 0 "register_operand" "")
1343 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1344 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1348 rtx t0 = gen_reg_rtx (SImode);
1349 rtx t1 = gen_reg_rtx (SImode);
1350 rtx t2 = gen_reg_rtx (SImode);
1351 rtx t3 = gen_reg_rtx (SImode);
1352 rtx t4 = gen_reg_rtx (SImode);
1353 rtx t5 = gen_reg_rtx (SImode);
1354 rtx t6 = gen_reg_rtx (SImode);
1355 rtx t7 = gen_reg_rtx (SImode);
1356 rtx t8 = gen_reg_rtx (SImode);
1357 rtx t9 = gen_reg_rtx (SImode);
1358 rtx t11 = gen_reg_rtx (SImode);
1359 rtx t12 = gen_reg_rtx (SImode);
1360 rtx t14 = gen_reg_rtx (SImode);
1361 rtx t15 = gen_reg_rtx (HImode);
1362 rtx t16 = gen_reg_rtx (HImode);
1363 rtx t17 = gen_reg_rtx (HImode);
1364 rtx t18 = gen_reg_rtx (HImode);
1365 rtx t19 = gen_reg_rtx (SImode);
1366 rtx t20 = gen_reg_rtx (SImode);
1367 rtx t21 = gen_reg_rtx (SImode);
1368 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1369 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1370 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1371 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1373 emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1374 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1375 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1376 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1377 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1378 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1379 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1380 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1382 /* Gen carry bits (in t9 and t11). */
1383 emit_insn (gen_addsi3 (t8, t2, t3));
1384 emit_insn (gen_cg_si (t9, t2, t3));
1385 emit_insn (gen_cg_si (t11, t8, t4));
1387 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1388 emit_insn (gen_addx_si (t12, t5, t6, t9));
1389 emit_insn (gen_addx_si (t14, t12, t7, t11));
1391 /* mpys treats both operands as signed when we really want it to treat
1392 the first operand as signed and the second operand as unsigned.
1393 The code below corrects for that difference. */
1394 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1395 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1396 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1397 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1398 emit_insn (gen_extendhisi2 (t19, t17));
1399 emit_insn (gen_extendhisi2 (t20, t18));
1400 emit_insn (gen_addsi3 (t21, t19, t20));
1401 emit_insn (gen_addsi3 (operands[0], t14, t21));
1405 (define_expand "umulsi3_highpart"
1406 [(set (match_operand:SI 0 "register_operand" "")
1409 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1410 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1415 rtx t0 = gen_reg_rtx (SImode);
1416 rtx t1 = gen_reg_rtx (SImode);
1417 rtx t2 = gen_reg_rtx (SImode);
1418 rtx t3 = gen_reg_rtx (SImode);
1419 rtx t4 = gen_reg_rtx (SImode);
1420 rtx t5 = gen_reg_rtx (SImode);
1421 rtx t6 = gen_reg_rtx (SImode);
1422 rtx t7 = gen_reg_rtx (SImode);
1423 rtx t8 = gen_reg_rtx (SImode);
1424 rtx t9 = gen_reg_rtx (SImode);
1425 rtx t10 = gen_reg_rtx (SImode);
1426 rtx t12 = gen_reg_rtx (SImode);
1427 rtx t13 = gen_reg_rtx (SImode);
1428 rtx t14 = gen_reg_rtx (SImode);
1429 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1430 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1431 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1433 emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1434 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1435 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1436 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1437 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1438 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1439 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1440 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1441 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1443 /* Gen carry bits (in t10 and t12). */
1444 emit_insn (gen_addsi3 (t9, t1, t5));
1445 emit_insn (gen_cg_si (t10, t1, t5));
1446 emit_insn (gen_cg_si (t12, t9, t6));
1448 /* Gen high 32 bits in operand[0]. */
1449 emit_insn (gen_addx_si (t13, t4, t7, t10));
1450 emit_insn (gen_addx_si (t14, t13, t8, t12));
1451 emit_insn (gen_movsi (operands[0], t14));
1458 ;; Not necessarily the best implementation of divide but faster then
1459 ;; the default that gcc provides because this is inlined and it uses
1461 (define_insn "divmodsi4"
1462 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1463 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1464 (match_operand:SI 2 "spu_reg_operand" "r")))
1465 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1466 (mod:SI (match_dup 1)
1468 (clobber (match_scratch:SI 4 "=&r"))
1469 (clobber (match_scratch:SI 5 "=&r"))
1470 (clobber (match_scratch:SI 6 "=&r"))
1471 (clobber (match_scratch:SI 7 "=&r"))
1472 (clobber (match_scratch:SI 8 "=&r"))
1473 (clobber (match_scratch:SI 9 "=&r"))
1474 (clobber (match_scratch:SI 10 "=&r"))
1475 (clobber (match_scratch:SI 11 "=&r"))
1476 (clobber (match_scratch:SI 12 "=&r"))
1477 (clobber (reg:SI 130))]
1485 selb %8,%8,%1,%10\\n\\
1486 selb %9,%9,%2,%11\\n\\
1492 shlqbyi %3,%8,0\\n\\
1493 xor %11,%10,%11\\n\\
1497 1: or %12,%0,%5\\n\\
1498 rotqmbii %5,%5,-1\\n\\
1502 rotqmbii %4,%4,-1\\n\\
1503 selb %0,%12,%0,%6\\n\\
1505 selb %3,%7,%3,%6\\n\\
1509 selb %3,%8,%3,%10\\n\\
1511 [(set_attr "type" "multi0")
1512 (set_attr "length" "128")])
1514 (define_insn "udivmodsi4"
1515 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1516 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1517 (match_operand:SI 2 "spu_reg_operand" "r")))
1518 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1519 (umod:SI (match_dup 1)
1521 (clobber (match_scratch:SI 4 "=&r"))
1522 (clobber (match_scratch:SI 5 "=&r"))
1523 (clobber (match_scratch:SI 6 "=&r"))
1524 (clobber (match_scratch:SI 7 "=&r"))
1525 (clobber (match_scratch:SI 8 "=&r"))
1526 (clobber (reg:SI 130))]
1539 rotqmbii %5,%5,-1\\n\\
1543 rotqmbii %4,%4,-1\\n\\
1544 selb %0,%8,%0,%6\\n\\
1546 selb %3,%7,%3,%6\\n\\
1549 [(set_attr "type" "multi0")
1550 (set_attr "length" "80")])
1552 (define_insn_and_split "div<mode>3"
1553 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1554 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1555 (match_operand:VSF 2 "spu_reg_operand" "r")))
1556 (clobber (match_scratch:VSF 3 "=&r"))
1557 (clobber (match_scratch:VSF 4 "=&r"))]
1561 [(set (match_dup:VSF 0)
1562 (div:VSF (match_dup:VSF 1)
1564 (clobber (match_dup:VSF 3))
1565 (clobber (match_dup:VSF 4))]
1567 emit_insn(gen_frest_<mode>(operands[3], operands[2]));
1568 emit_insn(gen_fi_<mode>(operands[3], operands[2], operands[3]));
1569 emit_insn(gen_mul<mode>3(operands[4], operands[1], operands[3]));
1570 emit_insn(gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
1571 emit_insn(gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
1578 (define_insn_and_split "sqrtsf2"
1579 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1580 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1581 (clobber (match_scratch:SF 2 "=&r"))
1582 (clobber (match_scratch:SF 3 "=&r"))
1583 (clobber (match_scratch:SF 4 "=&r"))
1584 (clobber (match_scratch:SF 5 "=&r"))]
1588 [(set (match_dup:SF 0)
1589 (sqrt:SF (match_dup:SF 1)))
1590 (clobber (match_dup:SF 2))
1591 (clobber (match_dup:SF 3))
1592 (clobber (match_dup:SF 4))
1593 (clobber (match_dup:SF 5))]
1595 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1596 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1597 emit_insn(gen_frsqest_sf(operands[2],operands[1]));
1598 emit_insn(gen_fi_sf(operands[2],operands[1],operands[2]));
1599 emit_insn(gen_mulsf3(operands[5],operands[2],operands[1]));
1600 emit_insn(gen_mulsf3(operands[3],operands[5],operands[3]));
1601 emit_insn(gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1602 emit_insn(gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1606 (define_insn "frest_<mode>"
1607 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1608 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1611 [(set_attr "type" "shuf")])
1613 (define_insn "frsqest_<mode>"
1614 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1615 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1618 [(set_attr "type" "shuf")])
1620 (define_insn "fi_<mode>"
1621 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1622 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1623 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1626 [(set_attr "type" "fp7")])
1631 (define_insn "and<mode>3"
1632 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1633 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1634 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1638 and%j2i\t%0,%1,%J2")
1640 (define_insn "anddi3"
1641 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1642 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1643 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1647 and%k2i\t%0,%1,%K2")
1649 (define_insn "andti3"
1650 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1651 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1652 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1656 and%m2i\t%0,%1,%L2")
1658 (define_insn "andc_<mode>"
1659 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1660 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1661 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1665 (define_insn "nand_<mode>"
1666 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1667 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1668 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1675 (define_insn "ior<mode>3"
1676 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1677 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
1678 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
1685 (define_insn "iordi3"
1686 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
1687 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
1688 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
1695 (define_insn "iorti3"
1696 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
1697 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
1698 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
1705 (define_insn "orc_<mode>"
1706 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1707 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1708 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1712 (define_insn "nor_<mode>"
1713 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1714 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1715 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1721 (define_insn "xor<mode>3"
1722 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1723 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1724 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
1728 xor%j2i\t%0,%1,%S2")
1730 (define_insn "xordi3"
1731 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1732 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1733 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1737 xor%k2i\t%0,%1,%K2")
1739 (define_insn "xorti3"
1740 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1741 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1742 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1746 xor%m2i\t%0,%1,%L2")
1748 (define_insn "eqv_<mode>"
1749 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1750 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
1751 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
1757 (define_insn "one_cmpl<mode>2"
1758 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1759 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
1766 (define_expand "selb"
1767 [(set (match_operand 0 "spu_reg_operand" "")
1768 (unspec [(match_operand 1 "spu_reg_operand" "")
1769 (match_operand 2 "spu_reg_operand" "")
1770 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
1773 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
1774 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
1779 ;; This could be defined as a combination of logical operations, but at
1780 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
1781 (define_insn "_selb"
1782 [(set (match_operand 0 "spu_reg_operand" "=r")
1783 (unspec [(match_operand 1 "spu_reg_operand" "r")
1784 (match_operand 2 "spu_reg_operand" "r")
1785 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
1786 "GET_MODE(operands[0]) == GET_MODE(operands[1])
1787 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
1788 "selb\t%0,%1,%2,%3")
1791 ;; Misc. byte/bit operations
1792 ;; clz/ctz/ffs/popcount/parity
1795 (define_insn "clz<mode>2"
1796 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
1797 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
1801 (define_expand "ctz<mode>2"
1803 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
1804 (set (match_dup 3) (and:VSI (match_dup 1)
1806 (set (match_dup 4) (clz:VSI (match_dup 3)))
1807 (set (match_operand:VSI 0 "spu_reg_operand" "")
1808 (minus:VSI (match_dup 5) (match_dup 4)))]
1811 operands[2] = gen_reg_rtx (<MODE>mode);
1812 operands[3] = gen_reg_rtx (<MODE>mode);
1813 operands[4] = gen_reg_rtx (<MODE>mode);
1814 operands[5] = spu_const(<MODE>mode, 31);
1817 (define_expand "ffs<mode>2"
1819 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
1820 (set (match_dup 3) (and:VSI (match_dup 1)
1822 (set (match_dup 4) (clz:VSI (match_dup 3)))
1823 (set (match_operand:VSI 0 "spu_reg_operand" "")
1824 (minus:VSI (match_dup 5) (match_dup 4)))]
1827 operands[2] = gen_reg_rtx (<MODE>mode);
1828 operands[3] = gen_reg_rtx (<MODE>mode);
1829 operands[4] = gen_reg_rtx (<MODE>mode);
1830 operands[5] = spu_const(<MODE>mode, 32);
1833 (define_expand "popcountsi2"
1835 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
1838 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
1839 (set (match_operand:SI 0 "spu_reg_operand" "")
1840 (sign_extend:SI (match_dup 3)))]
1843 operands[2] = gen_reg_rtx (SImode);
1844 operands[3] = gen_reg_rtx (HImode);
1847 (define_expand "paritysi2"
1848 [(set (match_operand:SI 0 "spu_reg_operand" "")
1849 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
1852 operands[2] = gen_reg_rtx (SImode);
1853 emit_insn (gen_popcountsi2(operands[2], operands[1]));
1854 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
1858 (define_insn "cntb_si"
1859 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1860 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
1864 [(set_attr "type" "fxb")])
1866 (define_insn "cntb_v16qi"
1867 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1868 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
1872 [(set_attr "type" "fxb")])
1874 (define_insn "sumb_si"
1875 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
1876 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
1879 [(set_attr "type" "fxb")])
1884 (define_insn "ashl<mode>3"
1885 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1886 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1887 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
1892 [(set_attr "type" "fx3")])
1894 (define_insn_and_split "ashldi3"
1895 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1896 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1897 (match_operand:SI 2 "spu_shift_operand" "r,I")))
1898 (clobber (match_scratch:SI 3 "=&r,X"))]
1902 [(set (match_dup:DI 0)
1903 (ashift:DI (match_dup:DI 1)
1906 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
1907 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
1908 rtx op2 = operands[2];
1909 rtx op3 = operands[3];
1911 if (GET_CODE (operands[2]) == REG)
1913 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
1914 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
1915 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
1916 emit_insn (gen_shlqbi_ti (op0, op0, op3));
1920 HOST_WIDE_INT val = INTVAL (operands[2]);
1921 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
1922 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
1924 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
1929 (define_expand "ashlti3"
1930 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
1931 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
1932 (match_operand:SI 2 "spu_nonmem_operand" "")))
1933 (clobber (match_dup:TI 3))])]
1935 "if (GET_CODE (operands[2]) == CONST_INT)
1937 emit_insn(gen_ashlti3_imm(operands[0], operands[1], operands[2]));
1940 operands[3] = gen_reg_rtx (TImode);")
1942 (define_insn_and_split "ashlti3_imm"
1943 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1944 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1945 (match_operand:SI 2 "immediate_operand" "O,P")))]
1950 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
1951 [(set (match_dup:TI 0)
1952 (ashift:TI (match_dup:TI 1)
1954 (set (match_dup:TI 0)
1955 (ashift:TI (match_dup:TI 0)
1958 HOST_WIDE_INT val = INTVAL(operands[2]);
1959 operands[3] = GEN_INT (val&7);
1960 operands[4] = GEN_INT (val&0x78);
1962 [(set_attr "type" "shuf,shuf")])
1964 (define_insn_and_split "ashlti3_reg"
1965 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1966 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
1967 (match_operand:SI 2 "spu_reg_operand" "r")))
1968 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
1972 [(set (match_dup:TI 3)
1973 (ashift:TI (match_dup:TI 1)
1974 (and:SI (match_dup:SI 2)
1976 (set (match_dup:TI 0)
1977 (ashift:TI (match_dup:TI 3)
1978 (and:SI (match_dup:SI 2)
1982 (define_insn "shlqbybi_ti"
1983 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1984 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1985 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
1990 shlqbyi\t%0,%1,%2/8"
1991 [(set_attr "type" "shuf,shuf")])
1993 (define_insn "shlqbi_ti"
1994 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1995 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1996 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2002 [(set_attr "type" "shuf,shuf")])
2004 (define_insn "shlqby_ti"
2005 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2006 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2007 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2013 [(set_attr "type" "shuf,shuf")])
2018 (define_insn_and_split "lshr<mode>3"
2019 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2020 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2021 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
2022 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2026 rot<bh>mi\t%0,%1,%N2"
2027 "reload_completed && GET_CODE (operands[2]) == REG"
2028 [(set (match_dup:VHSI 3)
2029 (neg:VHSI (match_dup:VHSI 2)))
2030 (set (match_dup:VHSI 0)
2031 (lshiftrt:VHSI (match_dup:VHSI 1)
2032 (neg:VHSI (match_dup:VHSI 3))))]
2034 [(set_attr "type" "*,fx3")])
2037 (define_insn "rotm_<mode>"
2038 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2039 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2040 (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
2044 rot<bh>mi\t%0,%1,%2"
2045 [(set_attr "type" "fx3")])
2047 (define_expand "lshr<mode>3"
2048 [(parallel [(set (match_operand:DTI 0 "spu_reg_operand" "")
2049 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "")
2050 (match_operand:SI 2 "spu_nonmem_operand" "")))
2051 (clobber (match_dup:DTI 3))
2052 (clobber (match_dup:SI 4))
2053 (clobber (match_dup:SI 5))])]
2055 "if (GET_CODE (operands[2]) == CONST_INT)
2057 emit_insn(gen_lshr<mode>3_imm(operands[0], operands[1], operands[2]));
2060 operands[3] = gen_reg_rtx (<MODE>mode);
2061 operands[4] = gen_reg_rtx (SImode);
2062 operands[5] = gen_reg_rtx (SImode);")
2064 (define_insn_and_split "lshr<mode>3_imm"
2065 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2066 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2067 (match_operand:SI 2 "immediate_operand" "O,P")))]
2070 rotqmbyi\t%0,%1,%N2/8
2071 rotqmbii\t%0,%1,%N2"
2072 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2073 [(set (match_dup:DTI 0)
2074 (lshiftrt:DTI (match_dup:DTI 1)
2076 (set (match_dup:DTI 0)
2077 (lshiftrt:DTI (match_dup:DTI 0)
2080 HOST_WIDE_INT val = INTVAL(operands[2]);
2081 operands[4] = GEN_INT (val&7);
2082 operands[5] = GEN_INT (val&0x78);
2084 [(set_attr "type" "shuf,shuf")])
2086 (define_insn_and_split "lshr<mode>3_reg"
2087 [(set (match_operand:DTI 0 "spu_reg_operand" "=r")
2088 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r")
2089 (match_operand:SI 2 "spu_reg_operand" "r")))
2090 (clobber (match_operand:DTI 3 "spu_reg_operand" "=&r"))
2091 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
2092 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))]
2096 [(set (match_dup:DTI 3)
2097 (lshiftrt:DTI (match_dup:DTI 1)
2098 (and:SI (neg:SI (match_dup:SI 4))
2100 (set (match_dup:DTI 0)
2101 (lshiftrt:DTI (match_dup:DTI 3)
2102 (and:SI (neg:SI (match_dup:SI 5))
2105 emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2]));
2106 emit_insn(gen_subsi3(operands[5], GEN_INT(7), operands[2]));
2109 (define_insn "rotqmbybi_<mode>"
2110 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2111 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2112 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2117 rotqmbyi\t%0,%1,%2/8"
2118 [(set_attr "type" "shuf")])
2120 (define_insn "rotqmbi_<mode>"
2121 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2122 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2123 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2129 [(set_attr "type" "shuf")])
2131 (define_insn "rotqmby_<mode>"
2132 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2133 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2134 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2140 [(set_attr "type" "shuf")])
2145 (define_insn_and_split "ashr<mode>3"
2146 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2147 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2148 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
2149 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2153 rotma<bh>i\t%0,%1,%N2"
2154 "reload_completed && GET_CODE (operands[2]) == REG"
2155 [(set (match_dup:VHSI 3)
2156 (neg:VHSI (match_dup:VHSI 2)))
2157 (set (match_dup:VHSI 0)
2158 (ashiftrt:VHSI (match_dup:VHSI 1)
2159 (neg:VHSI (match_dup:VHSI 3))))]
2161 [(set_attr "type" "*,fx3")])
2164 (define_insn "rotma_<mode>"
2165 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2166 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2167 (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
2171 rotma<bh>i\t%0,%1,%2"
2172 [(set_attr "type" "fx3")])
2174 (define_insn_and_split "ashrdi3"
2175 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2176 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2177 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2178 (clobber (match_scratch:TI 3 "=&r,&r"))
2179 (clobber (match_scratch:TI 4 "=&r,&r"))
2180 (clobber (match_scratch:SI 5 "=&r,&r"))]
2184 [(set (match_dup:DI 0)
2185 (ashiftrt:DI (match_dup:DI 1)
2188 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2189 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2190 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2191 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2192 rtx op2 = operands[2];
2193 rtx op3 = operands[3];
2194 rtx op4 = operands[4];
2195 rtx op5 = operands[5];
2197 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2199 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2200 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2201 emit_insn (gen_spu_fsm (op0v, op0s));
2203 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2205 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2206 HOST_WIDE_INT val = INTVAL (op2);
2207 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2208 emit_insn (gen_spu_xswd (op0d, op0v));
2210 emit_insn (gen_ashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2214 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2215 unsigned char arr[16] = {
2216 0xff, 0xff, 0xff, 0xff,
2217 0xff, 0xff, 0xff, 0xff,
2218 0x00, 0x00, 0x00, 0x00,
2219 0x00, 0x00, 0x00, 0x00
2222 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2223 emit_move_insn (op4, array_to_constant (TImode, arr));
2224 emit_insn (gen_spu_fsm (op3v, op5));
2226 if (GET_CODE (operands[2]) == REG)
2228 emit_insn (gen_selb (op4, op3, op1, op4));
2229 emit_insn (gen_negsi2 (op5, op2));
2230 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2231 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2235 HOST_WIDE_INT val = -INTVAL (op2);
2236 emit_insn (gen_selb (op0, op3, op1, op4));
2238 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2240 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2247 (define_expand "ashrti3"
2248 [(set (match_operand:TI 0 "spu_reg_operand" "")
2249 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "")
2250 (match_operand:SI 2 "spu_nonmem_operand" "")))]
2253 rtx sign_shift = gen_reg_rtx (SImode);
2254 rtx sign_mask = gen_reg_rtx (TImode);
2255 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2256 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2257 rtx t = gen_reg_rtx (TImode);
2258 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2259 emit_insn (gen_ashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2260 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2261 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2262 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2263 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2267 ;; fsm is used after rotam to replicate the sign across the whole register.
2268 (define_insn "fsm_ti"
2269 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2270 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2273 [(set_attr "type" "shuf")])
2278 (define_insn "rotl<mode>3"
2279 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2280 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2281 (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
2286 [(set_attr "type" "fx3")])
2288 (define_insn "rotlti3"
2289 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2290 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2291 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2294 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2297 rotqbyi\t%0,%1,%2/8\;rotqbii\t%0,%0,%2%%8"
2298 [(set_attr "length" "8,4,4,8")
2299 (set_attr "type" "multi1,shuf,shuf,multi1")])
2301 (define_insn "rotqbybi_ti"
2302 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2303 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2304 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2309 rotqbyi\t%0,%1,%2/8"
2310 [(set_attr "type" "shuf,shuf")])
2312 (define_insn "rotqby_ti"
2313 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2314 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2315 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2321 [(set_attr "type" "shuf,shuf")])
2323 (define_insn "rotqbi_ti"
2324 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2325 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2326 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2331 rotqbii\t%0,%1,%2%%8"
2332 [(set_attr "type" "shuf,shuf")])
2335 ;; struct extract/insert
2336 ;; We have to handle mem's because GCC will generate invalid SUBREG's
2337 ;; if it handles them. We generate better code anyway.
2339 (define_expand "extv"
2340 [(set (match_operand 0 "register_operand" "")
2341 (sign_extract (match_operand 1 "register_operand" "")
2342 (match_operand:SI 2 "const_int_operand" "")
2343 (match_operand:SI 3 "const_int_operand" "")))]
2345 { spu_expand_extv(operands, 0); DONE; })
2347 (define_expand "extzv"
2348 [(set (match_operand 0 "register_operand" "")
2349 (zero_extract (match_operand 1 "register_operand" "")
2350 (match_operand:SI 2 "const_int_operand" "")
2351 (match_operand:SI 3 "const_int_operand" "")))]
2353 { spu_expand_extv(operands, 1); DONE; })
2355 (define_expand "insv"
2356 [(set (zero_extract (match_operand 0 "register_operand" "")
2357 (match_operand:SI 1 "const_int_operand" "")
2358 (match_operand:SI 2 "const_int_operand" ""))
2359 (match_operand 3 "nonmemory_operand" ""))]
2361 { spu_expand_insv(operands); DONE; })
2364 ;; String/block move insn.
2365 ;; Argument 0 is the destination
2366 ;; Argument 1 is the source
2367 ;; Argument 2 is the length
2368 ;; Argument 3 is the alignment
2370 (define_expand "movstrsi"
2371 [(parallel [(set (match_operand:BLK 0 "" "")
2372 (match_operand:BLK 1 "" ""))
2373 (use (match_operand:SI 2 "" ""))
2374 (use (match_operand:SI 3 "" ""))])]
2378 if (spu_expand_block_move (operands))
2387 (define_insn "indirect_jump"
2388 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2391 [(set_attr "type" "br")])
2395 (label_ref (match_operand 0 "" "")))]
2398 [(set_attr "type" "br")])
2403 ;; This will be used for leaf functions, that don't save any regs and
2404 ;; don't have locals on stack, maybe... that is for functions that
2405 ;; don't change $sp and don't need to save $lr.
2406 (define_expand "return"
2411 ;; used in spu_expand_epilogue to generate return from a function and
2412 ;; explicitly set use of $lr.
2414 (define_insn "_return"
2418 [(set_attr "type" "br")])
2424 (define_insn "ceq_<mode>"
2425 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2426 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2427 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2431 ceq<bh>i\t%0,%1,%2")
2433 (define_insn_and_split "ceq_di"
2434 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2435 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2436 (match_operand:DI 2 "spu_reg_operand" "r")))]
2440 [(set (match_dup:SI 0)
2441 (eq:SI (match_dup:DI 1)
2444 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2445 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2446 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2447 emit_insn (gen_ceq_v4si (op0, op1, op2));
2448 emit_insn (gen_spu_gb (op0, op0));
2449 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2454 ;; We provide the TI compares for completeness and because some parts of
2455 ;; gcc/libgcc use them, even though user code might never see it.
2456 (define_insn "ceq_ti"
2457 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2458 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2459 (match_operand:TI 2 "spu_reg_operand" "r")))]
2461 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2462 [(set_attr "type" "multi0")
2463 (set_attr "length" "12")])
2465 (define_insn "ceq_<mode>"
2466 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2467 (eq:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
2468 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2472 (define_insn "cmeq_<mode>"
2473 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2474 (eq:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2475 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2479 (define_insn "ceq_vec"
2480 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2481 (eq:SI (match_operand 1 "spu_reg_operand" "r")
2482 (match_operand 2 "spu_reg_operand" "r")))]
2483 "VECTOR_MODE_P(GET_MODE(operands[1]))
2484 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2485 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2486 [(set_attr "length" "12")])
2491 (define_insn "cgt_<mode>"
2492 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2493 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2494 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2498 cgt<bh>i\t%0,%1,%2")
2500 (define_insn "cgt_di_m1"
2501 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2502 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2507 (define_insn_and_split "cgt_di"
2508 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2509 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
2510 (match_operand:DI 2 "spu_reg_operand" "r")))
2511 (clobber (match_scratch:V4SI 3 "=&r"))
2512 (clobber (match_scratch:V4SI 4 "=&r"))
2513 (clobber (match_scratch:V4SI 5 "=&r"))]
2517 [(set (match_dup:SI 0)
2518 (gt:SI (match_dup:DI 1)
2521 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2522 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2523 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2524 rtx op3 = operands[3];
2525 rtx op4 = operands[4];
2526 rtx op5 = operands[5];
2527 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
2528 emit_insn (gen_clgt_v4si (op3, op1, op2));
2529 emit_insn (gen_ceq_v4si (op4, op1, op2));
2530 emit_insn (gen_cgt_v4si (op5, op1, op2));
2531 emit_insn (gen_spu_xswd (op3d, op3));
2532 emit_insn (gen_selb (op0, op5, op3, op4));
2536 (define_insn "cgt_ti"
2537 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2538 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
2539 (match_operand:TI 2 "spu_reg_operand" "r")))
2540 (clobber (match_scratch:V4SI 3 "=&r"))
2541 (clobber (match_scratch:V4SI 4 "=&r"))
2542 (clobber (match_scratch:V4SI 5 "=&r"))]
2548 selb\t%0,%4,%0,%3\;\
2550 selb\t%0,%4,%0,%3\;\
2553 [(set_attr "type" "multi0")
2554 (set_attr "length" "36")])
2556 (define_insn "cgt_<mode>"
2557 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2558 (gt:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
2559 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2563 (define_insn "cmgt_<mode>"
2564 [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
2565 (gt:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2566 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2573 (define_insn "clgt_<mode>"
2574 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2575 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2576 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2580 clgt<bh>i\t%0,%1,%2")
2582 (define_insn_and_split "clgt_di"
2583 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2584 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
2585 (match_operand:DI 2 "spu_reg_operand" "r")))
2586 (clobber (match_scratch:V4SI 3 "=&r"))
2587 (clobber (match_scratch:V4SI 4 "=&r"))
2588 (clobber (match_scratch:V4SI 5 "=&r"))]
2592 [(set (match_dup:SI 0)
2593 (gtu:SI (match_dup:DI 1)
2596 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2597 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2598 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2599 rtx op3 = operands[3];
2600 rtx op4 = operands[4];
2601 rtx op5 = operands[5];
2602 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
2603 emit_insn (gen_clgt_v4si (op3, op1, op2));
2604 emit_insn (gen_ceq_v4si (op4, op1, op2));
2605 emit_insn (gen_spu_xswd (op5d, op3));
2606 emit_insn (gen_selb (op0, op3, op5, op4));
2610 (define_insn "clgt_ti"
2611 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2612 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
2613 (match_operand:TI 2 "spu_reg_operand" "r")))
2614 (clobber (match_scratch:V4SI 3 "=&r"))
2615 (clobber (match_scratch:V4SI 4 "=&r"))]
2620 selb\t%0,%4,%0,%3\;\
2622 selb\t%0,%4,%0,%3\;\
2625 [(set_attr "type" "multi0")
2626 (set_attr "length" "32")])
2633 (if_then_else (match_operator 1 "branch_comparison_operator"
2635 "spu_reg_operand" "r")
2637 (label_ref (match_operand 0 "" ""))
2641 [(set_attr "type" "br")])
2645 (if_then_else (match_operator 0 "branch_comparison_operator"
2647 "spu_reg_operand" "r")
2653 [(set_attr "type" "br")])
2657 (if_then_else (match_operator 1 "branch_comparison_operator"
2659 "spu_reg_operand" "r")
2662 (label_ref (match_operand 0 "" ""))))]
2665 [(set_attr "type" "br")])
2669 (if_then_else (match_operator 0 "branch_comparison_operator"
2671 "spu_reg_operand" "r")
2677 [(set_attr "type" "br")])
2680 ;; Compare insns are next. Note that the spu has two types of compares,
2681 ;; signed & unsigned, and one type of branch.
2683 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
2684 ;; insns, and branches. We store the operands of compares until we see
2687 (define_expand "cmp<mode>"
2689 (compare (match_operand:VQHSI 0 "spu_reg_operand" "")
2690 (match_operand:VQHSI 1 "spu_nonmem_operand" "")))]
2693 spu_compare_op0 = operands[0];
2694 spu_compare_op1 = operands[1];
2698 (define_expand "cmp<mode>"
2700 (compare (match_operand:DTI 0 "spu_reg_operand" "")
2701 (match_operand:DTI 1 "spu_reg_operand" "")))]
2704 spu_compare_op0 = operands[0];
2705 spu_compare_op1 = operands[1];
2709 (define_expand "cmp<mode>"
2711 (compare (match_operand:VSF 0 "spu_reg_operand" "")
2712 (match_operand:VSF 1 "spu_reg_operand" "")))]
2715 spu_compare_op0 = operands[0];
2716 spu_compare_op1 = operands[1];
2721 ;; branch on condition
2723 (define_expand "beq"
2724 [(use (match_operand 0 "" ""))]
2726 { spu_emit_branch_or_set (0, EQ, operands); DONE; })
2728 (define_expand "bne"
2729 [(use (match_operand 0 "" ""))]
2731 { spu_emit_branch_or_set (0, NE, operands); DONE; })
2733 (define_expand "bge"
2734 [(use (match_operand 0 "" ""))]
2736 { spu_emit_branch_or_set (0, GE, operands); DONE; })
2738 (define_expand "bgt"
2739 [(use (match_operand 0 "" ""))]
2741 { spu_emit_branch_or_set (0, GT, operands); DONE; })
2743 (define_expand "ble"
2744 [(use (match_operand 0 "" ""))]
2746 { spu_emit_branch_or_set (0, LE, operands); DONE; })
2748 (define_expand "blt"
2749 [(use (match_operand 0 "" ""))]
2751 { spu_emit_branch_or_set (0, LT, operands); DONE; })
2753 (define_expand "bgeu"
2754 [(use (match_operand 0 "" ""))]
2756 { spu_emit_branch_or_set (0, GEU, operands); DONE; })
2758 (define_expand "bgtu"
2759 [(use (match_operand 0 "" ""))]
2761 { spu_emit_branch_or_set (0, GTU, operands); DONE; })
2763 (define_expand "bleu"
2764 [(use (match_operand 0 "" ""))]
2766 { spu_emit_branch_or_set (0, LEU, operands); DONE; })
2768 (define_expand "bltu"
2769 [(use (match_operand 0 "" ""))]
2771 { spu_emit_branch_or_set (0, LTU, operands); DONE; })
2776 (define_expand "seq"
2777 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2779 { spu_emit_branch_or_set (1, EQ, operands); DONE; })
2781 (define_expand "sne"
2782 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2784 { spu_emit_branch_or_set (1, NE, operands); DONE; })
2786 (define_expand "sgt"
2787 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2789 { spu_emit_branch_or_set (1, GT, operands); DONE; })
2791 (define_expand "slt"
2792 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2794 { spu_emit_branch_or_set (1, LT, operands); DONE; })
2796 (define_expand "sge"
2797 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2799 { spu_emit_branch_or_set (1, GE, operands); DONE; })
2801 (define_expand "sle"
2802 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2804 { spu_emit_branch_or_set (1, LE, operands); DONE; })
2806 (define_expand "sgtu"
2807 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2809 { spu_emit_branch_or_set (1, GTU, operands); DONE; })
2811 (define_expand "sltu"
2812 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2814 { spu_emit_branch_or_set (1, LTU, operands); DONE; })
2816 (define_expand "sgeu"
2817 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2819 { spu_emit_branch_or_set (1, GEU, operands); DONE; })
2821 (define_expand "sleu"
2822 [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
2824 { spu_emit_branch_or_set (1, LEU, operands); DONE; })
2829 ;; Define this first one so HAVE_conditional_move is defined.
2830 (define_insn "movcc_dummy"
2831 [(set (match_operand 0 "" "")
2832 (if_then_else (match_operand 1 "" "")
2833 (match_operand 2 "" "")
2834 (match_operand 3 "" "")))]
2838 (define_expand "mov<mode>cc"
2839 [(set (match_operand:ALL 0 "spu_reg_operand" "")
2840 (if_then_else:ALL (match_operand 1 "comparison_operator" "")
2841 (match_operand:ALL 2 "spu_reg_operand" "")
2842 (match_operand:ALL 3 "spu_reg_operand" "")))]
2845 spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
2849 ;; This pattern is used when the result of a compare is not large
2850 ;; enough to use in a selb when expanding conditional moves.
2851 (define_expand "extend_compare"
2852 [(set (match_operand 0 "spu_reg_operand" "=r")
2853 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
2856 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2857 gen_rtx_UNSPEC (GET_MODE (operands[0]),
2858 gen_rtvec (1, operands[1]),
2859 UNSPEC_EXTEND_CMP)));
2863 (define_insn "extend_compare<mode>"
2864 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2865 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
2868 [(set_attr "type" "shuf")])
2873 ;; operand 0 is index
2874 ;; operand 1 is the minimum bound
2875 ;; operand 2 is the maximum bound - minimum bound + 1
2876 ;; operand 3 is CODE_LABEL for the table;
2877 ;; operand 4 is the CODE_LABEL to go to if index out of range.
2878 (define_expand "casesi"
2879 [(match_operand:SI 0 "spu_reg_operand" "")
2880 (match_operand:SI 1 "immediate_operand" "")
2881 (match_operand:SI 2 "immediate_operand" "")
2882 (match_operand 3 "" "")
2883 (match_operand 4 "" "")]
2886 rtx table = gen_reg_rtx (SImode);
2887 rtx index = gen_reg_rtx (SImode);
2888 rtx sindex = gen_reg_rtx (SImode);
2889 rtx addr = gen_reg_rtx (Pmode);
2891 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
2893 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
2894 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
2895 emit_move_insn (addr, gen_rtx_MEM (SImode,
2896 gen_rtx_PLUS (SImode, table, sindex)));
2898 emit_insn (gen_addsi3 (addr, addr, table));
2900 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
2901 emit_jump_insn (gen_tablejump (addr, operands[3]));
2905 (define_insn "tablejump"
2906 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
2907 (use (label_ref (match_operand 1 "" "")))]
2910 [(set_attr "type" "br")])
2915 ;; Note that operand 1 is total size of args, in bytes,
2916 ;; and what the call insn wants is the number of words.
2917 (define_expand "sibcall"
2919 [(call (match_operand:QI 0 "call_operand" "")
2920 (match_operand:QI 1 "" ""))
2924 if (! call_operand (operands[0], QImode))
2925 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2928 (define_insn "_sibcall"
2930 [(call (match_operand:QI 0 "call_operand" "R,S")
2931 (match_operand:QI 1 "" "i,i"))
2933 "SIBLING_CALL_P(insn)"
2937 [(set_attr "type" "br,br")])
2939 (define_expand "sibcall_value"
2941 [(set (match_operand 0 "" "")
2942 (call (match_operand:QI 1 "call_operand" "")
2943 (match_operand:QI 2 "" "")))
2947 if (! call_operand (operands[1], QImode))
2948 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2951 (define_insn "_sibcall_value"
2953 [(set (match_operand 0 "" "")
2954 (call (match_operand:QI 1 "call_operand" "R,S")
2955 (match_operand:QI 2 "" "i,i")))
2957 "SIBLING_CALL_P(insn)"
2961 [(set_attr "type" "br,br")])
2963 ;; Note that operand 1 is total size of args, in bytes,
2964 ;; and what the call insn wants is the number of words.
2965 (define_expand "call"
2967 [(call (match_operand:QI 0 "call_operand" "")
2968 (match_operand:QI 1 "" ""))
2969 (clobber (reg:SI 0))
2970 (clobber (reg:SI 130))])]
2973 if (! call_operand (operands[0], QImode))
2974 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2977 (define_insn "_call"
2979 [(call (match_operand:QI 0 "call_operand" "R,S,T")
2980 (match_operand:QI 1 "" "i,i,i"))
2981 (clobber (reg:SI 0))
2982 (clobber (reg:SI 130))])]
2988 [(set_attr "type" "br")])
2990 (define_expand "call_value"
2992 [(set (match_operand 0 "" "")
2993 (call (match_operand:QI 1 "call_operand" "")
2994 (match_operand:QI 2 "" "")))
2995 (clobber (reg:SI 0))
2996 (clobber (reg:SI 130))])]
2999 if (! call_operand (operands[1], QImode))
3000 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3003 (define_insn "_call_value"
3005 [(set (match_operand 0 "" "")
3006 (call (match_operand:QI 1 "call_operand" "R,S,T")
3007 (match_operand:QI 2 "" "i,i,i")))
3008 (clobber (reg:SI 0))
3009 (clobber (reg:SI 130))])]
3015 [(set_attr "type" "br")])
3017 (define_expand "untyped_call"
3018 [(parallel [(call (match_operand 0 "" "")
3020 (match_operand 1 "" "")
3021 (match_operand 2 "" "")])]
3025 rtx reg = gen_rtx_REG (TImode, 3);
3027 /* We need to use call_value so the return value registers don't get
3029 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
3031 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3033 rtx set = XVECEXP (operands[2], 0, i);
3034 emit_move_insn (SET_DEST (set), SET_SRC (set));
3037 /* The optimizer does not know that the call sets the function value
3038 registers we stored in the result block. We avoid problems by
3039 claiming that all hard registers are used and clobbered at this
3041 emit_insn (gen_blockage ());
3047 ;; Patterns used for splitting and combining.
3050 ;; Function prologue and epilogue.
3052 (define_expand "prologue"
3055 { spu_expand_prologue (); DONE; })
3057 ;; "blockage" is only emited in epilogue. This is what it took to
3058 ;; make "basic block reordering" work with the insns sequence
3059 ;; generated by the spu_expand_epilogue (taken from mips.md)
3061 (define_insn "blockage"
3062 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
3065 [(set_attr "length" "0")])
3067 (define_expand "epilogue"
3070 { spu_expand_epilogue (false); DONE; })
3072 (define_expand "sibcall_epilogue"
3075 { spu_expand_epilogue (true); DONE; })
3078 ;; stack manipulations
3080 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
3081 ;; We move the back-chain and decrement the stack pointer.
3082 (define_expand "allocate_stack"
3083 [(set (match_operand 0 "spu_reg_operand" "")
3084 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
3086 (minus (reg 1) (match_dup 1)))]
3088 "spu_allocate_stack (operands[0], operands[1]); DONE;")
3090 ;; These patterns say how to save and restore the stack pointer. We need not
3091 ;; save the stack pointer at function or block level since we are careful to
3092 ;; preserve the backchain. Doing nothing at block level means the stack space
3093 ;; is allocated until the end of the function. This is currently safe to do
3094 ;; because gcc uses the frame pointer for the whole function, so the worst that
3095 ;; happens is wasted stack space. That could be bad if a VLA is declared in a
3096 ;; loop, because new space will be allocated every iteration, but users can
3097 ;; work around that case. Ideally we could detect when we are in a loop and
3098 ;; generate the more complicated code in that case.
3100 ;; For nonlocal gotos, we must save both the stack pointer and its
3101 ;; backchain and restore both. Note that in the nonlocal case, the
3102 ;; save area is a memory location.
3104 (define_expand "save_stack_function"
3105 [(match_operand 0 "general_operand" "")
3106 (match_operand 1 "general_operand" "")]
3110 (define_expand "restore_stack_function"
3111 [(match_operand 0 "general_operand" "")
3112 (match_operand 1 "general_operand" "")]
3116 (define_expand "save_stack_block"
3117 [(match_operand 0 "general_operand" "")
3118 (match_operand 1 "general_operand" "")]
3122 (define_expand "restore_stack_block"
3123 [(use (match_operand 0 "spu_reg_operand" ""))
3124 (set (match_dup 2) (match_dup 3))
3125 (set (match_dup 0) (match_operand 1 "spu_reg_operand" ""))
3126 (set (match_dup 3) (match_dup 2))]
3130 (define_expand "save_stack_nonlocal"
3131 [(match_operand 0 "memory_operand" "")
3132 (match_operand 1 "spu_reg_operand" "")]
3136 rtx temp = gen_reg_rtx (Pmode);
3138 /* Copy the backchain to the first word, sp to the second. We need to
3139 save the back chain because __builtin_apply appears to clobber it. */
3140 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
3141 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
3142 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
3146 (define_expand "restore_stack_nonlocal"
3147 [(match_operand 0 "spu_reg_operand" "")
3148 (match_operand 1 "memory_operand" "")]
3152 spu_restore_stack_nonlocal(operands[0], operands[1]);
3159 ;; Vector initialization
3160 (define_expand "vec_init<mode>"
3161 [(match_operand:V 0 "register_operand" "")
3162 (match_operand 1 "" "")]
3165 spu_expand_vector_init (operands[0], operands[1]);
3169 (define_expand "vec_set<mode>"
3170 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
3171 (set (match_dup:TI 3)
3172 (unspec:TI [(match_dup:SI 4)
3174 (match_dup:SI 6)] UNSPEC_CPAT))
3175 (set (match_operand:V 0 "spu_reg_operand" "")
3176 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
3178 (match_dup:TI 3)] UNSPEC_SHUFB))]
3181 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
3182 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
3183 operands[3] = gen_reg_rtx (TImode);
3184 operands[4] = stack_pointer_rtx;
3185 operands[5] = offset;
3186 operands[6] = GEN_INT (size);
3189 (define_expand "vec_extract<mode>"
3190 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
3191 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
3192 (parallel [(match_operand 2 "const_int_operand" "i")])))]
3195 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
3197 emit_insn (gen_spu_convert (operands[0], operands[1]));
3202 (define_insn "_vec_extract<mode>"
3203 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
3204 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
3205 (parallel [(match_operand 2 "const_int_operand" "i")])))]
3207 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
3208 [(set_attr "type" "shuf")])
3213 (define_expand "shufb"
3214 [(set (match_operand 0 "spu_reg_operand" "")
3215 (unspec [(match_operand 1 "spu_reg_operand" "")
3216 (match_operand 2 "spu_reg_operand" "")
3217 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
3220 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
3221 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
3226 (define_insn "_shufb"
3227 [(set (match_operand 0 "spu_reg_operand" "=r")
3228 (unspec [(match_operand 1 "spu_reg_operand" "r")
3229 (match_operand 2 "spu_reg_operand" "r")
3230 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
3232 "shufb\t%0,%1,%2,%3"
3233 [(set_attr "type" "shuf")])
3236 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
3239 [(set_attr "type" "nop")])
3242 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
3245 [(set_attr "type" "nop")])
3248 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
3251 [(set_attr "type" "lnop")])
3253 (define_insn "iprefetch"
3254 [(unspec [(const_int 0)] UNSPEC_IPREFETCH)]
3257 [(set_attr "type" "iprefetch")])
3261 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s,s,s")
3262 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
3263 (unspec [(const_int 0)] UNSPEC_HBR)]
3269 [(set_attr "type" "hbr")])
3272 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
3273 (clobber (mem:BLK (scratch)))]
3276 [(set_attr "type" "br")])
3278 (define_insn "syncc"
3279 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
3280 (clobber (mem:BLK (scratch)))]
3283 [(set_attr "type" "br")])
3285 (define_insn "dsync"
3286 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
3287 (clobber (mem:BLK (scratch)))]
3290 [(set_attr "type" "br")])
3293 ;; convert between any two modes, avoiding any GCC assumptions
3294 (define_expand "spu_convert"
3295 [(set (match_operand 0 "spu_reg_operand" "")
3296 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
3299 rtx c = gen__spu_convert (operands[0], operands[1]);
3300 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
3305 (define_insn "_spu_convert"
3306 [(set (match_operand 0 "spu_reg_operand" "=r")
3307 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
3310 [(set_attr "type" "convert")
3311 (set_attr "length" "0")])
3314 [(set (match_operand 0 "spu_reg_operand")
3315 (unspec [(match_operand 1 "spu_reg_operand")] UNSPEC_CONVERT))]
3317 [(use (const_int 0))]
3322 (include "spu-builtins.md")
3325 (define_expand "smaxv4sf3"
3326 [(set (match_operand:V4SF 0 "register_operand" "=r")
3327 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
3328 (match_operand:V4SF 2 "register_operand" "r")))]
3332 rtx mask = gen_reg_rtx (V4SImode);
3334 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
3335 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
3339 (define_expand "sminv4sf3"
3340 [(set (match_operand:V4SF 0 "register_operand" "=r")
3341 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
3342 (match_operand:V4SF 2 "register_operand" "r")))]
3346 rtx mask = gen_reg_rtx (V4SImode);
3348 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
3349 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));