| ;; Copyright (C) 2006 Free Software Foundation, Inc. |
| |
| ;; This file is free software; you can redistribute it and/or modify it under |
| ;; the terms of the GNU General Public License as published by the Free |
| ;; Software Foundation; either version 2 of the License, or (at your option) |
| ;; any later version. |
| |
| ;; This file is distributed in the hope that it will be useful, but WITHOUT |
| ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| ;; for more details. |
| |
| ;; You should have received a copy of the GNU General Public License |
| ;; along with this file; see the file COPYING. If not, write to the Free |
| ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA |
| ;; 02110-1301, USA. |
| |
| |
| ;; This includes expands for all the intrinsics. |
| ;; spu_expand_builtin looks at the mode of match_operand. |
| |
| |
| ;; load/store |
| |
| (define_expand "spu_lqd" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_nonmem_operand" "")) |
| (const_int -16))))] |
| "" |
| { |
| if (GET_CODE (operands[2]) == CONST_INT |
| && (INTVAL (operands[2]) & 15) != 0) |
| operands[2] = GEN_INT (INTVAL (operands[2]) & -16); |
| if (GET_CODE (operands[2]) != CONST_INT) |
| { |
| rtx op2 = operands[2]; |
| operands[2] = force_reg (Pmode, operands[2]); |
| if (!ALIGNED_SYMBOL_REF_P (op2)) |
| emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16))); |
| } |
| }) |
| |
| (define_expand "spu_lqx" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_reg_operand" "")) |
| (const_int -16))))] |
| "" |
| "") |
| |
| (define_expand "spu_lqa" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "") |
| (const_int -16))))] |
| "" |
| { |
| if (GET_CODE (operands[1]) == CONST_INT |
| && (INTVAL (operands[1]) & 15) != 0) |
| operands[1] = GEN_INT (INTVAL (operands[1]) & -16); |
| }) |
| |
| (define_expand "spu_lqr" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (mem:TI (and:SI (match_operand:SI 1 "address_operand" "") |
| (const_int -16))))] |
| "" |
| "") |
| |
| (define_expand "spu_stqd" |
| [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_nonmem_operand" "")) |
| (const_int -16))) |
| (match_operand:TI 0 "spu_reg_operand" "r,r"))] |
| "" |
| { |
| if (GET_CODE (operands[2]) == CONST_INT |
| && (INTVAL (operands[2]) & 15) != 0) |
| operands[2] = GEN_INT (INTVAL (operands[2]) & -16); |
| if (GET_CODE (operands[2]) != CONST_INT) |
| { |
| rtx op2 = operands[2]; |
| operands[2] = force_reg (Pmode, operands[2]); |
| if (!ALIGNED_SYMBOL_REF_P (op2)) |
| emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16))); |
| } |
| }) |
| |
| (define_expand "spu_stqx" |
| [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_reg_operand" "")) |
| (const_int -16))) |
| (match_operand:TI 0 "spu_reg_operand" "r"))] |
| "" |
| "") |
| |
| (define_expand "spu_stqa" |
| [(set (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "") |
| (const_int -16))) |
| (match_operand:TI 0 "spu_reg_operand" "r"))] |
| "" |
| { |
| if (GET_CODE (operands[1]) == CONST_INT |
| && (INTVAL (operands[1]) & 15) != 0) |
| operands[1] = GEN_INT (INTVAL (operands[1]) & -16); |
| }) |
| |
| (define_expand "spu_stqr" |
| [(set (mem:TI (and:SI (match_operand:SI 1 "address_operand" "") |
| (const_int -16))) |
| (match_operand:TI 0 "spu_reg_operand" ""))] |
| "" |
| "") |
| |
| |
| ;; generate control word |
| |
| (define_expand "spu_cbx" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_nonmem_operand" "") |
| (const_int 1)] UNSPEC_CPAT))] |
| "" |
| "") |
| |
| (define_expand "spu_chx" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_nonmem_operand" "") |
| (const_int 2)] UNSPEC_CPAT))] |
| "" |
| "") |
| |
| (define_expand "spu_cwx" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_nonmem_operand" "") |
| (const_int 4)] UNSPEC_CPAT))] |
| "" |
| "") |
| |
| (define_expand "spu_cdx" |
| [(set (match_operand:TI 0 "spu_reg_operand" "") |
| (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "spu_nonmem_operand" "") |
| (const_int 8)] UNSPEC_CPAT))] |
| "" |
| "") |
| |
| |
| |
| ;; Constant formation |
| |
| (define_expand "spu_ilhu" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "") |
| (const_vector:V4SI [(match_operand:SI 1 "immediate_operand" "")]))] |
| "" |
| "{ emit_insn(gen_movv4si(operands[0], spu_const(V4SImode, (INTVAL(operands[1]) << 16)))); |
| DONE; |
| }") |
| |
| |
| ;; integer subtract |
| (define_expand "spu_sfh" |
| [(set (match_operand:V8HI 0 "spu_reg_operand" "") |
| (minus:V8HI (match_operand:V8HI 2 "spu_nonmem_operand" "") |
| (match_operand:V8HI 1 "spu_reg_operand" "")))] |
| "" |
| "") |
| |
| (define_expand "spu_sf" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "") |
| (minus:V4SI (match_operand:V4SI 2 "spu_nonmem_operand" "") |
| (match_operand:V4SI 1 "spu_reg_operand" "")))] |
| "" |
| "") |
| |
| (define_expand "spu_sfx" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "") |
| (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") |
| (match_operand:V4SI 1 "spu_reg_operand" "") |
| (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_SFX))] |
| "" |
| "") |
| |
| (define_expand "spu_bg" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "") |
| (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") |
| (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_BG))] |
| "" |
| "") |
| |
| (define_expand "spu_bgx" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "") |
| (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") |
| (match_operand:V4SI 1 "spu_reg_operand" "") |
| (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_BGX))] |
| "" |
| "") |
| |
| ;; integer multiply |
| (define_insn "spu_mpy" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r") |
| (mult:V4SI |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r,r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_arith_operand" "r,B") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))] |
| "" |
| "@ |
| mpy\t%0,%1,%2 |
| mpyi\t%0,%1,%H2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpyu" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r") |
| (mult:V4SI |
| (zero_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r,r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) |
| (zero_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_arith_operand" "r,B") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))] |
| "" |
| "@ |
| mpyu\t%0,%1,%2 |
| mpyui\t%0,%1,%H2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpya" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (plus:V4SI |
| (mult:V4SI |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) |
| (match_operand:V4SI 3 "spu_reg_operand" "r")))] |
| "" |
| "mpya\t%0,%1,%2,%3" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpyh" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (ashift:V4SI |
| (mult:V4SI |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) |
| (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))] |
| "" |
| "mpyh\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpys" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (ashiftrt:V4SI |
| (mult:V4SI |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) |
| (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))] |
| "" |
| "mpys\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpyhhu" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (mult:V4SI |
| (zero_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) |
| (zero_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))] |
| "" |
| "mpyhhu\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpyhh" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (mult:V4SI |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))] |
| "" |
| "mpyhh\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpyhhau" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (plus:V4SI |
| (mult:V4SI |
| (zero_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) |
| (zero_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))) |
| (match_operand:V4SI 3 "spu_reg_operand" "0")))] |
| "" |
| "mpyhhau\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_mpyhha" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (plus:V4SI |
| (mult:V4SI |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 2 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))) |
| (match_operand:V4SI 3 "spu_reg_operand" "0")))] |
| "" |
| "mpyhha\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| ;; form select mask |
| (define_insn "spu_fsmb" |
| [(set (match_operand:V16QI 0 "spu_reg_operand" "=r,r") |
| (unspec:V16QI [(match_operand:SI 1 "spu_nonmem_operand" "r,MN")] UNSPEC_FSMB))] |
| "" |
| "@ |
| fsmb\t%0,%1 |
| fsmbi\t%0,%1" |
| [(set_attr "type" "shuf")]) |
| |
| (define_insn "spu_fsmh" |
| [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") |
| (unspec:V8HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSMH))] |
| "" |
| "fsmh\t%0,%1" |
| [(set_attr "type" "shuf")]) |
| |
| (define_insn "spu_fsm" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSM))] |
| "" |
| "fsm\t%0,%1" |
| [(set_attr "type" "shuf")]) |
| |
| |
| ;; gather bits |
| (define_insn "spu_gbb" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:V16QI 1 "spu_reg_operand" "r")] UNSPEC_GBB))] |
| "" |
| "gbb\t%0,%1" |
| [(set_attr "type" "shuf")]) |
| |
| (define_insn "spu_gbh" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:V8HI 1 "spu_reg_operand" "r")] UNSPEC_GBH))] |
| "" |
| "gbh\t%0,%1" |
| [(set_attr "type" "shuf")]) |
| |
| (define_insn "spu_gb" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_GB))] |
| "" |
| "gb\t%0,%1" |
| [(set_attr "type" "shuf")]) |
| |
| ;; misc byte operations |
| (define_insn "spu_avgb" |
| [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") |
| (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r") |
| (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_AVGB))] |
| "" |
| "avgb\t%0,%1,%2" |
| [(set_attr "type" "fxb")]) |
| |
| (define_insn "spu_absdb" |
| [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") |
| (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r") |
| (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_ABSDB))] |
| "" |
| "absdb\t%0,%1,%2" |
| [(set_attr "type" "fxb")]) |
| |
| (define_insn "spu_sumb" |
| [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") |
| (unspec:V8HI [(match_operand:V16QI 1 "spu_reg_operand" "r") |
| (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_SUMB))] |
| "" |
| "sumb\t%0,%1,%2" |
| [(set_attr "type" "fxb")]) |
| |
| ;; sign extend |
| (define_insn "spu_xsbh" |
| [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") |
| (sign_extend:V8HI |
| (vec_select:V8QI |
| (match_operand:V16QI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7) |
| (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))] |
| "" |
| "xsbh\t%0,%1") |
| |
| (define_insn "spu_xshw" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (sign_extend:V4SI |
| (vec_select:V4HI |
| (match_operand:V8HI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))] |
| "" |
| "xshw\t%0,%1") |
| |
| (define_insn "spu_xswd" |
| [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") |
| (sign_extend:V2DI |
| (vec_select:V2SI |
| (match_operand:V4SI 1 "spu_reg_operand" "r") |
| (parallel [(const_int 1)(const_int 3)]))))] |
| "" |
| "xswd\t%0,%1") |
| |
| ;; or across |
| |
| (define_insn "spu_orx" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_ORX))] |
| "" |
| "orx\t%0,%1") |
| |
| |
| ;; compare & halt |
| (define_insn "spu_heq" |
| [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") |
| (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HEQ)] |
| "" |
| "@ |
| heq\t%0,%1 |
| heqi\t%0,%1") |
| |
| (define_insn "spu_hgt" |
| [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") |
| (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HGT)] |
| "" |
| "@ |
| hgt\t%0,%1 |
| hgti\t%0,%1") |
| |
| (define_insn "spu_hlgt" |
| [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") |
| (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HLGT)] |
| "" |
| "@ |
| hlgt\t%0,%1 |
| hlgti\t%0,%1") |
| |
| ;; branches |
| |
| ;; The description below hides the fact that bisled conditionally |
| ;; executes the call depending on the value in channel 0. This was |
| ;; done so that the description would conform to the format of a call |
| ;; insn. Otherwise (if this were not part of call insn), the link |
| ;; register, $lr, would not be saved/restored in the prologue/epilogue. |
| |
| (define_insn "spu_bisled" |
| [(parallel |
| [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) |
| (const_int 0)) |
| (clobber (reg:SI 0)) |
| (clobber (reg:SI 130)) |
| (use (match_operand:SI 1 "address_operand" "")) |
| (use (const_int 0))])] |
| "" |
| "bisled\t$lr,%0" |
| [(set_attr "type" "br")]) |
| |
| (define_insn "spu_bisledd" |
| [(parallel |
| [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) |
| (const_int 0)) |
| (clobber (reg:SI 0)) |
| (clobber (reg:SI 130)) |
| (use (match_operand:SI 1 "address_operand" "")) |
| (use (const_int 1))])] |
| "" |
| "bisledd\t$lr,%0" |
| [(set_attr "type" "br")]) |
| |
| (define_insn "spu_bislede" |
| [(parallel |
| [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) |
| (const_int 0)) |
| (clobber (reg:SI 0)) |
| (clobber (reg:SI 130)) |
| (use (match_operand:SI 1 "address_operand" "")) |
| (use (const_int 2))])] |
| "" |
| "bislede\t$lr,%0" |
| [(set_attr "type" "br")]) |
| |
| ;; float convert |
| (define_insn "spu_csflt" |
| [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") |
| (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r") |
| (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CSFLT ))] |
| "" |
| "csflt\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_cflts" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r") |
| (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTS ))] |
| "" |
| "cflts\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_cuflt" |
| [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") |
| (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r") |
| (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CUFLT ))] |
| "" |
| "cuflt\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_insn "spu_cfltu" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r") |
| (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTU ))] |
| "" |
| "cfltu\t%0,%1,%2" |
| [(set_attr "type" "fp7")]) |
| |
| (define_expand "spu_frds" |
| [(set (match_operand:V4SF 0 "spu_reg_operand" "") |
| (vec_select:V4SF |
| (vec_concat:V4SF |
| (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "")) |
| (match_dup:V2SF 2)) |
| (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))] |
| "" |
| "operands[2] = spu_const(V2SFmode, 0);") |
| |
| (define_insn "_frds" |
| [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") |
| (vec_select:V4SF |
| (vec_concat:V4SF |
| (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r")) |
| (match_operand:V2SF 2 "vec_imm_operand" "i")) |
| (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))] |
| "" |
| "frds\t%0,%1" |
| [(set_attr "type" "fpd")]) |
| |
| (define_insn "spu_fesd" |
| [(set (match_operand:V2DF 0 "spu_reg_operand" "=r") |
| (float_extend:V2DF |
| (vec_select:V2SF |
| (match_operand:V4SF 1 "spu_reg_operand" "r") |
| (parallel [(const_int 0)(const_int 2)]))))] |
| "" |
| "fesd\t%0,%1" |
| [(set_attr "type" "fpd")]) |
| |
| ;; control |
| (define_insn "spu_stop" |
| [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)] |
| "" |
| "stop\t%0" |
| [(set_attr "type" "br")]) |
| |
| (define_insn "spu_stopd" |
| [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r") |
| (match_operand:SI 1 "spu_reg_operand" "r") |
| (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)] |
| "" |
| "stopd\t%0,%1,%2" |
| [(set_attr "type" "br")]) |
| |
| ;; interrupt disable/enable |
| ;; Register 131 is used exclusively for enabling/disabling interrupts. |
| ;; It is marked as a global reg and the instructions clobber mem, so it will |
| ;; not be incorrectly optimized. |
| (define_expand "spu_idisable" |
| [(parallel |
| [(set (reg:INTR 131) (const_int 0)) |
| (clobber (match_dup:SI 0)) |
| (clobber (mem:BLK (scratch)))])] |
| "" |
| "operands[0] = gen_reg_rtx (SImode);") |
| |
| (define_expand "spu_ienable" |
| [(parallel |
| [(set (reg:INTR 131) (const_int 1)) |
| (clobber (match_dup:SI 0)) |
| (clobber (mem:BLK (scratch)))])] |
| "" |
| "operands[0] = gen_reg_rtx (SImode);") |
| |
| (define_insn "set_intr" |
| [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i")) |
| (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) |
| (clobber (mem:BLK (scratch)))] |
| "! flag_pic" |
| "ila\t%0,.+8\;bi%I1\t%0" |
| [(set_attr "length" "8") |
| (set_attr "type" "multi0")]) |
| |
| (define_insn "set_intr_pic" |
| [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i")) |
| (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) |
| (clobber (mem:BLK (scratch)))] |
| "flag_pic" |
| "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0" |
| [(set_attr "length" "12") |
| (set_attr "type" "multi1")]) |
| |
| (define_expand "movintrcc" |
| [(parallel |
| [(set (match_operand:INTR 0 "spu_reg_operand" "") |
| (if_then_else:INTR (match_operand 1 "branch_comparison_operator" "") |
| (match_operand 3 "const_int_operand" "") |
| (match_operand:INTR 2 "spu_reg_operand" ""))) |
| (clobber (match_dup:SI 4)) |
| (clobber (mem:BLK (scratch)))])] |
| "" |
| { /* We've swapped operands 2 and 3 in the pattern, reverse the |
| condition code too. */ |
| PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); |
| operands[4] = gen_reg_rtx (SImode); |
| }) |
| |
| (define_insn "set_intr_cc" |
| [(set (reg:INTR 131) |
| (if_then_else:INTR |
| (match_operator 1 "branch_comparison_operator" |
| [(match_operand 2 "spu_reg_operand" "r") |
| (const_int 0)]) |
| (match_operand:SI 3 "const_int_operand" "i") |
| (reg:INTR 131))) |
| (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) |
| (clobber (mem:BLK (scratch)))] |
| "! flag_pic" |
| "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0" |
| [(set_attr "length" "8") |
| (set_attr "type" "multi0")]) |
| |
| (define_insn "set_intr_cc_pic" |
| [(set (reg:INTR 131) |
| (if_then_else:INTR |
| (match_operator 1 "branch_comparison_operator" |
| [(match_operand 2 "spu_reg_operand" "r") |
| (const_int 0)]) |
| (match_operand:SI 3 "const_int_operand" "i") |
| (reg:INTR 131))) |
| (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) |
| (clobber (mem:BLK (scratch)))] |
| "flag_pic" |
| "brsl\t%0,.+4\;ai\t%0,%0,8\;%b2%b1z%I3\t%2,%0" |
| [(set_attr "length" "12") |
| (set_attr "type" "multi1")]) |
| |
| (define_insn "set_intr_return" |
| [(set (reg:INTR 131) (match_operand 0 "const_int_operand" "i")) |
| (return)] |
| "" |
| "bi%I0\t$lr" |
| [(set_attr "type" "br")]) |
| |
| (define_peephole2 |
| [(parallel |
| [(set (reg:INTR 131) (match_operand 0 "const_int_operand")) |
| (clobber (match_operand:SI 1 "spu_reg_operand")) |
| (clobber (mem:BLK (scratch)))]) |
| (use (reg:SI 0)) |
| (return)] |
| "" |
| [(use (reg:SI 0)) |
| (parallel |
| [(set (reg:INTR 131) (match_dup 0)) |
| (return)])] |
| "") |
| |
| ;; special purpose registers |
| (define_insn "spu_fscrrd" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))] |
| "" |
| "fscrrd\t%0" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_fscrwr" |
| [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)] |
| "" |
| "fscrwr\t$0,%0" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_mfspr" |
| [(set (match_operand:SI 0 "spu_reg_operand" "=r") |
| (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))] |
| "" |
| "mfspr\t%0,$sp%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_mtspr" |
| [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") |
| (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)] |
| "" |
| "mtspr\t$sp%0,%1" |
| [(set_attr "type" "spr")]) |
| |
| ;; channels |
| (define_expand "spu_rdch" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "") |
| (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))] |
| "" |
| "{ |
| if (spu_safe_dma (INTVAL (operands[1]))) |
| { |
| emit_insn (gen_spu_rdch_clobber (operands[0], operands[1])); |
| DONE; |
| } |
| }") |
| |
| (define_expand "spu_rchcnt" |
| [(set (match_operand:SI 0 "spu_reg_operand" "") |
| (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))] |
| "" |
| "{ |
| if (spu_safe_dma (INTVAL (operands[1]))) |
| { |
| emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1])); |
| DONE; |
| } |
| }") |
| |
| (define_expand "spu_wrch" |
| [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "") |
| (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)] |
| "" |
| "{ |
| if (spu_safe_dma (INTVAL (operands[0]))) |
| { |
| emit_insn (gen_spu_wrch_clobber (operands[0], operands[1])); |
| DONE; |
| } |
| }") |
| |
| (define_insn "spu_rdch_noclobber" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))] |
| "" |
| "rdch\t%0,$ch%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_rchcnt_noclobber" |
| [(set (match_operand:SI 0 "spu_reg_operand" "=r") |
| (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))] |
| "" |
| "rchcnt\t%0,$ch%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_wrch_noclobber" |
| [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") |
| (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)] |
| "" |
| "wrch\t$ch%0,%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_rdch_clobber" |
| [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") |
| (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH)) |
| (clobber (mem:BLK (scratch)))] |
| "" |
| "rdch\t%0,$ch%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_rchcnt_clobber" |
| [(set (match_operand:SI 0 "spu_reg_operand" "=r") |
| (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT)) |
| (clobber (mem:BLK (scratch)))] |
| "" |
| "rchcnt\t%0,$ch%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_insn "spu_wrch_clobber" |
| [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") |
| (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH) |
| (clobber (mem:BLK (scratch)))] |
| "" |
| "wrch\t$ch%0,%1" |
| [(set_attr "type" "spr")]) |
| |
| (define_expand "spu_splats" |
| [(set (match_operand 0 "spu_reg_operand" "") |
| (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))] |
| "" |
| { |
| spu_builtin_splats(operands); |
| DONE; |
| }) |
| |
| (define_expand "spu_extract" |
| [(set (match_operand 0 "spu_reg_operand" "") |
| (unspec [(match_operand 1 "spu_reg_operand" "") |
| (match_operand 2 "spu_nonmem_operand" "")] 0))] |
| "" |
| { |
| spu_builtin_extract (operands); |
| DONE; |
| }) |
| |
| (define_expand "spu_insert" |
| [(set (match_operand 0 "spu_reg_operand" "") |
| (unspec [(match_operand 1 "spu_reg_operand" "") |
| (match_operand 2 "spu_reg_operand" "") |
| (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] |
| "" |
| { |
| spu_builtin_insert(operands); |
| DONE; |
| }) |
| |
| (define_expand "spu_promote" |
| [(set (match_operand 0 "spu_reg_operand" "") |
| (unspec [(match_operand 1 "spu_reg_operand" "") |
| (match_operand:SI 2 "immediate_operand" "")] 0))] |
| "" |
| { |
| spu_builtin_promote(operands); |
| DONE; |
| }) |
| |
| ;; Currently doing nothing with this but expanding its args. |
| (define_expand "spu_align_hint" |
| [(unspec [(match_operand:SI 0 "address_operand" "") |
| (match_operand:SI 1 "immediate_operand" "") |
| (match_operand:SI 2 "immediate_operand" "")] 0)] |
| "" |
| { |
| DONE; |
| }) |
| |