basic multimedia patch applied to SH gcc port
Joern Rennecke
joern.rennecke@superh.com
Mon Jul 1 12:44:00 GMT 2002
Tested for sh64-elf.
--
--------------------------
SuperH
2430 Aztec West / Almondsbury / BRISTOL / BS32 4AQ
T:+44 1454 462330
-------------- next part --------------
Mon Jul 1 19:55:17 2002 J"orn Rennecke <joern.rennecke@superh.com>
* sh.c (langhooks.h): Include.
(sh_init_builtins, sh_media_init_builtins): New functions.
(sh_expand_builtin, arith_reg_dest,and_operand): Likewise.
(mextr_bit_offset, extend_reg_operand, zero_vec_operand): Likewise.
(sh_rep_vec, sh_1el_vec, sh_const_vec): Likewise.
(builtin_description): New struct tag.
(signature_args, bdesc): New arrays.
(TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Undef / define.
(print_operand): Add 'N' modifier.
* sh.h (VECTOR_MODE_SUPPORTED_P): Add SHmedia vector modes.
(EXTRA_CONSTRAINT_U, EXTRA_CONSTRAINT_W): New macros.
(EXTRA_CONSTRAINT): Add 'U' and 'W' cases.
(CONST_COSTS): Add special case for SHmedia AND.
(PREDICATE_CODES): Add and_operand, arith_reg_dest,
extend_reg_operand, extend_reg_or_0_operand, mextr_bit_offset,
sh_const_vec, sh_1el_vec, sh_rep_vec, zero_vec_operand.
target_operand can also be const or unspec.
* sh.md (UNSPEC_INIT_TRAMP, UNSPEC_FCOSA UNSPEC_FSRRA): New constants.
(UNSPEC_FSINA, UNSPEC_NSB, UNSPEC_ALLOCO): Likewise.
(attribute type): Add new types.
(anddi3): Add splitter.
(movdi_const_16bit+1): Add code to handle vector constants and
bitmasks efficiently.
(shori_media): Have generator function made.
(movv8qi, movv8qi_i, movv8qi_i+1, movv8qi_i+2): New patterns.
(movv8qi_i+3, movv2hi, movv2hi_i, movv4hi, movv4hi_i): Likewise.
(movv2si, movv2si_i, absv2si2, absv4hi2, addv2si3, addv4hi3): Likewise.
(ssaddv2si3, usaddv8qi3, ssaddv4hi3, negcmpeqv8qi): Likewise.
(negcmpeqv2si, negcmpeqv4hi, negcmpgtuv8qi, negcmpgtv2si): Likewise.
(negcmpgtv4hi, mcmv, mcnvs_lw, mcnvs_wb, mcnvs_wub): Likewise.
(mextr_rl, mextr_lr, mextr1, mextr2, mextr3, mextr4, mextr5): Likewise.
(mextr6, mextr7, mmacfx_wl, mmacfx_wl_i, mmacnfx_wl): Likewise.
(mmacnfx_wl_i, mulv2si3, mulv4hi3, mmulfx_l, mmulfx_w): Likewise.
(mmulfxrp_w, mmulhi_wl, mmullo_wl, mmul23_wl, mmul01_wl): Likewise.
(mmulsum_wq, mmulsum_wq_i, mperm_w, mperm_w_little): LIkewise.
(mperm_w_big, mperm_w0, msad_ubq, msad_ubq_i, mshalds_l): Likewise.
(mshalds_w, ashrv2si3, ashrv4hi3, mshards_q, mshfhi_b): Likewise.
(mshflo_b, mshf4_b, mshf0_b, mshfhi_l, mshflo_l, mshf4_l): Likewsie.
(mshf0_l, mshfhi_w, mshflo_w, mshf4_w, mshf0_w, mshfhi_l_di): Likewise.
(mshfhi_l_di_rev, mshflo_l_di, mshflo_l_di_rev): Likewise.
(mshflo_l_di_x, mshflo_l_di_x_rev, ashlv2si3, ashlv4hi3): Likewise.
(lshrv2si3, lshrv4hi3, subv2si3, subv4hi3, sssubv2si3): Likewise.
(ussubv8qi3, sssubv4hi3, fcosa_s, fsina_s, fipr, fsrra_s): Likewise.
(ftrv): Likewise.
(fpu_switch+1, fpu_switch+2): Remove constraint.
Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.153
diff -p -r1.153 sh.c
*** config/sh/sh.c 18 Jun 2002 19:03:15 -0000 1.153
--- config/sh/sh.c 1 Jul 2002 18:54:58 -0000
*************** Boston, MA 02111-1307, USA. */
*** 42,47 ****
--- 42,48 ----
#include "target.h"
#include "target-def.h"
#include "real.h"
+ #include "langhooks.h"
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
*************** static bool sh_ms_bitfield_layout_p PARA
*** 204,209 ****
--- 205,214 ----
static void sh_encode_section_info PARAMS ((tree, int));
static const char *sh_strip_name_encoding PARAMS ((const char *));
+ static void sh_init_builtins (void);
+ static void sh_media_init_builtins (void);
+ static rtx sh_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
*************** static const char *sh_strip_name_encodin
*** 247,252 ****
--- 252,262 ----
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING sh_strip_name_encoding
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS sh_init_builtins
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN sh_expand_builtin
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Print the operand address in x to the stream. */
*************** print_operand_address (stream, x)
*** 320,325 ****
--- 330,336 ----
'S' print the MSW of a dp value - changes if in little endian
'T' print the next word of a dp value - same as 'R' in big endian mode.
'M' print an `x' if `m' will print `base,index'.
+ 'N' print 'r63' if the operand is (const_int 0).
'm' print a pair `base,offset' or `base,index', for LD and ST.
'u' prints the lowest 16 bits of CONST_INT, as an unsigned value.
'o' output an operator. */
*************** print_operand (stream, x, code)
*** 422,427 ****
--- 433,445 ----
}
break;
+ case 'N':
+ if (x == const0_rtx)
+ {
+ fprintf ((stream), "r63");
+ break;
+ }
+ goto default_output;
case 'u':
if (GET_CODE (x) == CONST_INT)
{
*************** print_operand (stream, x, code)
*** 430,435 ****
--- 448,454 ----
}
/* Fall through. */
+ default_output:
default:
switch (GET_CODE (x))
{
*************** arith_reg_operand (op, mode)
*** 5846,5851 ****
--- 5865,5884 ----
return 0;
}
+ /* Like above, but for DImode destinations: forbid paradoxical DImode subregs,
+ because this would lead to missing sign extensions when truncating from
+ DImode to SImode. */
+ int
+ arith_reg_dest (op, mode)
+ rtx op;
+ enum machine_mode mode;
+ {
+ if (mode == DImode && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
+ return 0;
+ return arith_reg_operand (op, mode);
+ }
+
int
fp_arith_reg_operand (op, mode)
rtx op;
*************** logical_operand (op, mode)
*** 5948,5953 ****
--- 5981,6005 ----
return 0;
}
+ int
+ and_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+ {
+ if (logical_operand (op, mode))
+ return 1;
+
+ /* Check mshflo.l / mshflhi.l opportunities. */
+ if (TARGET_SHMEDIA
+ && mode == DImode
+ && GET_CODE (op) == CONST_INT
+ && (INTVAL (op) == (unsigned) 0xffffffff
+ || INTVAL (op) == (HOST_WIDE_INT) -1 << 32))
+ return 1;
+
+ return 0;
+ }
+
/* Nonzero if OP is a floating point value with value 0.0. */
int
*************** target_operand (op, mode)
*** 6129,6134 ****
--- 6181,6315 ----
return target_reg_operand (op, mode);
}
+ int
+ mextr_bit_offset (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+ HOST_WIDE_INT i;
+
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ i = INTVAL (op);
+ return i >= 1*8 && i <= 7*8 && (i & 7) == 0;
+ }
+
+ int
+ extend_reg_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+ {
+ return (GET_CODE (op) == TRUNCATE
+ ? arith_operand
+ : arith_reg_operand) (op, mode);
+ }
+
+ int
+ extend_reg_or_0_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+ {
+ return (GET_CODE (op) == TRUNCATE
+ ? arith_operand
+ : arith_reg_or_0_operand) (op, mode);
+ }
+
+ /* Return nonzero if V is a zero vector matching MODE. */
+ int
+ zero_vec_operand (v, mode)
+ rtx v;
+ enum machine_mode mode;
+ {
+ int i;
+
+ if (GET_CODE (v) != PARALLEL
+ || (GET_MODE (v) != mode && mode != VOIDmode))
+ return 0;
+ for (i = XVECLEN (v, 0) - 1; i >= 0; i--)
+ if (XVECEXP (v, 0, i) != const0_rtx)
+ return 0;
+ return 1;
+ }
+
+ int
+ sh_rep_vec (v, mode)
+ rtx v;
+ enum machine_mode mode;
+ {
+ int i;
+ rtx x, y;
+
+ if ((GET_CODE (v) != CONST_VECTOR && GET_CODE (v) != PARALLEL)
+ || (GET_MODE (v) != mode && mode != VOIDmode))
+ return 0;
+ i = XVECLEN (v, 0) - 2;
+ x = XVECEXP (v, 0, i + 1);
+ if (GET_MODE_UNIT_SIZE (mode) == 1)
+ {
+ y = XVECEXP (v, 0, i);
+ for (i -= 2 ; i >= 0; i -= 2)
+ if (! rtx_equal_p (XVECEXP (v, 0, i + 1), x)
+ || ! rtx_equal_p (XVECEXP (v, 0, i), y))
+ return 0;
+ }
+ else
+ for (; i >= 0; i--)
+ if (XVECEXP (v, 0, i) != x)
+ return 0;
+ return 1;
+ }
+
+ /* Determine if V is a constant vector matching MODE with only one element
+ that is not a sign extension. Two byte-sized elements count as one. */
+ int
+ sh_1el_vec (v, mode)
+ rtx v;
+ enum machine_mode mode;
+ {
+ int unit_size;
+ int i, last, least, sign_ix;
+ rtx sign;
+
+ if (GET_CODE (v) != CONST_VECTOR
+ || (GET_MODE (v) != mode && mode != VOIDmode))
+ return 0;
+ /* Determine numbers of last and of least significat elements. */
+ last = XVECLEN (v, 0) - 1;
+ least = TARGET_LITTLE_ENDIAN ? 0 : last;
+ if (GET_CODE (XVECEXP (v, 0, least)) != CONST_INT)
+ return 0;
+ sign_ix = least;
+ if (GET_MODE_UNIT_SIZE (mode) == 1)
+ sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
+ if (GET_CODE (XVECEXP (v, 0, sign_ix)) != CONST_INT)
+ return 0;
+ unit_size = GET_MODE_UNIT_SIZE (GET_MODE (v));
+ sign = (INTVAL (XVECEXP (v, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
+ ? constm1_rtx : const0_rtx);
+ i = XVECLEN (v, 0) - 1;
+ do
+ if (i != least && i != sign_ix && XVECEXP (v, 0, i) != sign)
+ return 0;
+ while (--i);
+ return 1;
+ }
+
+ int
+ sh_const_vec (v, mode)
+ rtx v;
+ enum machine_mode mode;
+ {
+ int i;
+
+ if (GET_CODE (v) != CONST_VECTOR
+ || (GET_MODE (v) != mode && mode != VOIDmode))
+ return 0;
+ i = XVECLEN (v, 0) - 1;
+ for (; i >= 0; i--)
+ if (GET_CODE (XVECEXP (v, 0, i)) != CONST_INT)
+ return 0;
+ return 1;
+ }
/* Return the destination address of a branch. */
*************** sh_insn_length_adjustment (insn)
*** 6446,6453 ****
/* Instructions with unfilled delay slots take up an extra two bytes for
the nop in the delay slot. */
if (((GET_CODE (insn) == INSN
! && GET_CODE (PATTERN (insn)) != USE
! && GET_CODE (PATTERN (insn)) != CLOBBER)
|| GET_CODE (insn) == CALL_INSN
|| (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
--- 6627,6634 ----
/* Instructions with unfilled delay slots take up an extra two bytes for
the nop in the delay slot. */
if (((GET_CODE (insn) == INSN
! && GET_CODE (PATTERN (insn)) != USE
! && GET_CODE (PATTERN (insn)) != CLOBBER)
|| GET_CODE (insn) == CALL_INSN
|| (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
*************** legitimize_pic_address (orig, mode, reg)
*** 6588,6594 ****
/* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */
! static rtx mark_constant_pool_use (x)
rtx x;
{
rtx insn, lab, pattern;
--- 6769,6776 ----
/* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */
! static rtx
! mark_constant_pool_use (x)
rtx x;
{
rtx insn, lab, pattern;
*************** sh_strip_name_encoding (str)
*** 6848,6851 ****
--- 7030,7328 ----
return str;
}
+
+ /* Machine specific built-in functions. */
+
+ struct builtin_description
+ {
+ const enum insn_code icode;
+ const char *const name;
+ int signature;
+ };
+
+ /* describe number and signedness of arguments; arg[0] == result
+ (1: unsigned, 2: signed, 4: don't care, 8: pointer 0: no argument */
+ static const char signature_args[][4] =
+ {
+ #define SH_BLTIN_V2SI2 0
+ { 4, 4 },
+ #define SH_BLTIN_V4HI2 1
+ { 4, 4 },
+ #define SH_BLTIN_V2SI3 2
+ { 4, 4, 4 },
+ #define SH_BLTIN_V4HI3 3
+ { 4, 4, 4 },
+ #define SH_BLTIN_V8QI3 4
+ { 4, 4, 4 },
+ #define SH_BLTIN_MAC_HISI 5
+ { 1, 4, 4, 1 },
+ #define SH_BLTIN_SH_HI 6
+ { 4, 4, 1 },
+ #define SH_BLTIN_SH_SI 7
+ { 4, 4, 1 },
+ #define SH_BLTIN_V4HI2V2SI 8
+ { 4, 4, 4 },
+ #define SH_BLTIN_V4HI2V8QI 9
+ { 4, 4, 4 },
+ #define SH_BLTIN_SISF 10
+ { 4, 2 },
+ #define SH_BLTIN_LDUA_L 11
+ { 2, 8 },
+ #define SH_BLTIN_LDUA_Q 12
+ { 1, 8 },
+ #define SH_BLTIN_STUA_L 13
+ { 0, 8, 2 },
+ #define SH_BLTIN_STUA_Q 14
+ { 0, 8, 1 },
+ #define SH_BLTIN_NUM_SHARED_SIGNATURES 15
+ #define SH_BLTIN_2 15
+ #define SH_BLTIN_SU 15
+ { 1, 2 },
+ #define SH_BLTIN_3 16
+ #define SH_BLTIN_SUS 16
+ { 2, 2, 1 },
+ #define SH_BLTIN_PSSV 17
+ { 0, 8, 2, 2 },
+ #define SH_BLTIN_XXUU 18
+ #define SH_BLTIN_UUUU 18
+ { 1, 1, 1, 1 },
+ #define SH_BLTIN_PV 19
+ { 0, 8 },
+ };
+ /* mcmv: operands considered unsigned. */
+ /* mmulsum_wq, msad_ubq: result considered unsigned long long. */
+ /* mperm: control value considered unsigned int. */
+ /* mshalds, mshard, mshards, mshlld, mshlrd: shift count is unsigned int. */
+ /* mshards_q: returns signed short. */
+ /* nsb: takes long long arg, returns unsigned char. */
+ static const struct builtin_description bdesc[] =
+ {
+ { CODE_FOR_absv2si2, "__builtin_absv2si2", SH_BLTIN_V2SI2 },
+ { CODE_FOR_absv4hi2, "__builtin_absv4hi2", SH_BLTIN_V4HI2 },
+ { CODE_FOR_addv2si3, "__builtin_addv2si3", SH_BLTIN_V2SI3 },
+ { CODE_FOR_addv4hi3, "__builtin_addv4hi3", SH_BLTIN_V4HI3 },
+ { CODE_FOR_ssaddv2si3,"__builtin_ssaddv2si3", SH_BLTIN_V2SI3 },
+ { CODE_FOR_usaddv8qi3,"__builtin_usaddv8qi3", SH_BLTIN_V8QI3 },
+ { CODE_FOR_ssaddv4hi3,"__builtin_ssaddv4hi3", SH_BLTIN_V4HI3 },
+ #if 0
+ { CODE_FOR_alloco32, "__builtin_sh_media_ALLOCO", SH_BLTIN_PV },
+ { CODE_FOR_alloco64, "__builtin_sh_media_ALLOCO", SH_BLTIN_PV },
+ #endif
+ { CODE_FOR_negcmpeqv8qi,"__builtin_sh_media_MCMPEQ_B", SH_BLTIN_V8QI3 },
+ { CODE_FOR_negcmpeqv2si,"__builtin_sh_media_MCMPEQ_L", SH_BLTIN_V2SI3 },
+ { CODE_FOR_negcmpeqv4hi,"__builtin_sh_media_MCMPEQ_W", SH_BLTIN_V4HI3 },
+ { CODE_FOR_negcmpgtuv8qi,"__builtin_sh_media_MCMPGT_UB", SH_BLTIN_V8QI3 },
+ { CODE_FOR_negcmpgtv2si,"__builtin_sh_media_MCMPGT_L", SH_BLTIN_V2SI3 },
+ { CODE_FOR_negcmpgtv4hi,"__builtin_sh_media_MCMPGT_W", SH_BLTIN_V4HI3 },
+ { CODE_FOR_mcmv, "__builtin_sh_media_MCMV", SH_BLTIN_UUUU },
+ { CODE_FOR_mcnvs_lw, "__builtin_sh_media_MCNVS_LW", SH_BLTIN_3 },
+ { CODE_FOR_mcnvs_wb, "__builtin_sh_media_MCNVS_WB", SH_BLTIN_V4HI2V8QI },
+ { CODE_FOR_mcnvs_wub, "__builtin_sh_media_MCNVS_WUB", SH_BLTIN_V4HI2V8QI },
+ { CODE_FOR_mextr1, "__builtin_sh_media_MEXTR1", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr2, "__builtin_sh_media_MEXTR2", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr3, "__builtin_sh_media_MEXTR3", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr4, "__builtin_sh_media_MEXTR4", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr5, "__builtin_sh_media_MEXTR5", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr6, "__builtin_sh_media_MEXTR6", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr7, "__builtin_sh_media_MEXTR7", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mmacfx_wl, "__builtin_sh_media_MMACFX_WL", SH_BLTIN_MAC_HISI },
+ { CODE_FOR_mmacnfx_wl,"__builtin_sh_media_MMACNFX_WL", SH_BLTIN_MAC_HISI },
+ { CODE_FOR_mulv2si3, "__builtin_mulv2si3", SH_BLTIN_V2SI3, },
+ { CODE_FOR_mulv4hi3, "__builtin_mulv4hi3", SH_BLTIN_V4HI3 },
+ { CODE_FOR_mmulfx_l, "__builtin_sh_media_MMULFX_L", SH_BLTIN_V2SI3 },
+ { CODE_FOR_mmulfx_w, "__builtin_sh_media_MMULFX_W", SH_BLTIN_V4HI3 },
+ { CODE_FOR_mmulfxrp_w,"__builtin_sh_media_MMULFXRP_W", SH_BLTIN_V4HI3 },
+ { CODE_FOR_mmulhi_wl, "__builtin_sh_media_MMULHI_WL", SH_BLTIN_V4HI2V2SI },
+ { CODE_FOR_mmullo_wl, "__builtin_sh_media_MMULLO_WL", SH_BLTIN_V4HI2V2SI },
+ { CODE_FOR_mmulsum_wq,"__builtin_sh_media_MMULSUM_WQ", SH_BLTIN_XXUU },
+ { CODE_FOR_mperm_w, "__builtin_sh_media_MPERM_W", SH_BLTIN_SH_HI },
+ { CODE_FOR_msad_ubq, "__builtin_sh_media_MSAD_UBQ", SH_BLTIN_XXUU },
+ { CODE_FOR_mshalds_l, "__builtin_sh_media_MSHALDS_L", SH_BLTIN_SH_SI },
+ { CODE_FOR_mshalds_w, "__builtin_sh_media_MSHALDS_W", SH_BLTIN_SH_HI },
+ { CODE_FOR_ashrv2si3, "__builtin_ashrv2si3", SH_BLTIN_SH_SI },
+ { CODE_FOR_ashrv4hi3, "__builtin_ashrv4hi3", SH_BLTIN_SH_HI },
+ { CODE_FOR_mshards_q, "__builtin_sh_media_MSHARDS_Q", SH_BLTIN_SUS },
+ { CODE_FOR_mshfhi_b, "__builtin_sh_media_MSHFHI_B", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mshfhi_l, "__builtin_sh_media_MSHFHI_L", SH_BLTIN_V2SI3 },
+ { CODE_FOR_mshfhi_w, "__builtin_sh_media_MSHFHI_W", SH_BLTIN_V4HI3 },
+ { CODE_FOR_mshflo_b, "__builtin_sh_media_MSHFLO_B", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mshflo_l, "__builtin_sh_media_MSHFLO_L", SH_BLTIN_V2SI3 },
+ { CODE_FOR_mshflo_w, "__builtin_sh_media_MSHFLO_W", SH_BLTIN_V4HI3 },
+ { CODE_FOR_ashlv2si3, "__builtin_ashlv2si3", SH_BLTIN_SH_SI },
+ { CODE_FOR_ashlv4hi3, "__builtin_ashlv4hi3", SH_BLTIN_SH_HI },
+ { CODE_FOR_lshrv2si3, "__builtin_lshrv2si3", SH_BLTIN_SH_SI },
+ { CODE_FOR_lshrv4hi3, "__builtin_lshrv4hi3", SH_BLTIN_SH_HI },
+ { CODE_FOR_subv2si3, "__builtin_subv2si3", SH_BLTIN_V2SI3 },
+ { CODE_FOR_subv4hi3, "__builtin_subv4hi3", SH_BLTIN_V4HI3 },
+ { CODE_FOR_sssubv2si3,"__builtin_sssubv2si3", SH_BLTIN_V2SI3 },
+ { CODE_FOR_ussubv8qi3,"__builtin_ussubv8qi3", SH_BLTIN_V8QI3 },
+ { CODE_FOR_sssubv4hi3,"__builtin_sssubv4hi3", SH_BLTIN_V4HI3 },
+ { CODE_FOR_fcosa_s, "__builtin_sh_media_FCOSA_S", SH_BLTIN_SISF },
+ { CODE_FOR_fsina_s, "__builtin_sh_media_FSINA_S", SH_BLTIN_SISF },
+ { CODE_FOR_fipr, "__builtin_sh_media_FIPR_S", SH_BLTIN_3 },
+ { CODE_FOR_ftrv, "__builtin_sh_media_FTRV_S", SH_BLTIN_3 },
+ { CODE_FOR_fsrra_s, "__builtin_sh_media_FSRRA_S", SH_BLTIN_2 },
+ #if 0
+ { CODE_FOR_ldhi_l, "__builtin_sh_media_LDHI_L", SH_BLTIN_LDUA_L },
+ { CODE_FOR_ldhi_q, "__builtin_sh_media_LDHI_Q", SH_BLTIN_LDUA_Q },
+ { CODE_FOR_ldlo_l, "__builtin_sh_media_LDLO_L", SH_BLTIN_LDUA_L },
+ { CODE_FOR_ldlo_q, "__builtin_sh_media_LDLO_Q", SH_BLTIN_LDUA_Q },
+ { CODE_FOR_sthi_l, "__builtin_sh_media_STHI_L", SH_BLTIN_STUA_L },
+ { CODE_FOR_sthi_q, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q },
+ { CODE_FOR_stlo_l, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L },
+ { CODE_FOR_stlo_q, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q },
+ { CODE_FOR_ldhi_l64, "__builtin_sh_media_LDHI_L", SH_BLTIN_LDUA_L },
+ { CODE_FOR_ldhi_q64, "__builtin_sh_media_LDHI_Q", SH_BLTIN_LDUA_Q },
+ { CODE_FOR_ldlo_l64, "__builtin_sh_media_LDLO_L", SH_BLTIN_LDUA_L },
+ { CODE_FOR_ldlo_q64, "__builtin_sh_media_LDLO_Q", SH_BLTIN_LDUA_Q },
+ { CODE_FOR_sthi_l64, "__builtin_sh_media_STHI_L", SH_BLTIN_STUA_L },
+ { CODE_FOR_sthi_q64, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q },
+ { CODE_FOR_stlo_l64, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L },
+ { CODE_FOR_stlo_q64, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q },
+ { CODE_FOR_nsb, "__builtin_sh_media_NSB", SH_BLTIN_SU },
+ { CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2 },
+ { CODE_FOR_prefetch32,"__builtin_sh_media_PREFO", SH_BLTIN_PSSV },
+ { CODE_FOR_prefetch64,"__builtin_sh_media_PREFO", SH_BLTIN_PSSV }
+ #endif
+ };
+
+ static void
+ sh_media_init_builtins ()
+ {
+ tree shared[SH_BLTIN_NUM_SHARED_SIGNATURES];
+ const struct builtin_description *d;
+
+ bzero (shared, sizeof shared);
+ for (d = bdesc; d - bdesc < sizeof bdesc / sizeof bdesc[0]; d++)
+ {
+ tree type, arg_type;
+ int signature = d->signature;
+ int i;
+
+ if (signature < SH_BLTIN_NUM_SHARED_SIGNATURES && shared[signature])
+ type = shared[signature];
+ else
+ {
+ int has_result = signature_args[signature][0] != 0;
+
+ if (signature_args[signature][1] == 8
+ && (insn_data[d->icode].operand[has_result].mode != Pmode))
+ continue;
+ if (! TARGET_FPU_ANY
+ && FLOAT_MODE_P (insn_data[d->icode].operand[0].mode))
+ continue;
+ type = void_list_node;
+ for (i = 3; ; i--)
+ {
+ int arg = signature_args[signature][i];
+ int opno = i - 1 + has_result;
+
+ if (arg == 8)
+ arg_type = ptr_type_node;
+ else if (arg)
+ arg_type = ((*lang_hooks.types.type_for_mode)
+ (insn_data[d->icode].operand[opno].mode,
+ (arg & 1)));
+ else if (i)
+ continue;
+ else
+ arg_type = void_type_node;
+ if (i == 0)
+ break;
+ type = tree_cons (NULL_TREE, arg_type, type);
+ }
+ type = build_function_type (arg_type, type);
+ if (signature < SH_BLTIN_NUM_SHARED_SIGNATURES)
+ shared[signature] = type;
+ }
+ builtin_function (d->name, type, d - bdesc, BUILT_IN_MD, NULL);
+ }
+ }
+
+ static void
+ sh_init_builtins ()
+ {
+ if (TARGET_SHMEDIA)
+ sh_media_init_builtins ();
+ }
+
+ /* Expand an expression EXP that calls a built-in function,
+ with result going to TARGET if that's convenient
+ (and in mode MODE if that's convenient).
+ SUBTARGET may be used as the target for computing one of EXP's operands.
+ IGNORE is nonzero if the value is to be ignored. */
+
+ static rtx
+ sh_expand_builtin (exp, target, subtarget, mode, ignore)
+ tree exp;
+ rtx target;
+ rtx subtarget ATTRIBUTE_UNUSED;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ int ignore;
+ {
+ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ tree arglist = TREE_OPERAND (exp, 1);
+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ const struct builtin_description *d = &bdesc[fcode];
+ enum insn_code icode = d->icode;
+ int signature = d->signature;
+ enum machine_mode tmode = VOIDmode;
+ int nop = 0, i;
+ rtx op[4];
+ rtx pat;
+
+ if (signature_args[signature][0])
+ {
+ if (ignore)
+ return 0;
+
+ tmode = insn_data[icode].operand[0].mode;
+ if (! target
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ op[nop++] = target;
+ }
+ else
+ target = 0;
+
+ for (i = 1; i <= 3; i++, nop++)
+ {
+ tree arg;
+ enum machine_mode opmode, argmode;
+
+ if (! signature_args[signature][i])
+ break;
+ arg = TREE_VALUE (arglist);
+ arglist = TREE_CHAIN (arglist);
+ opmode = insn_data[icode].operand[nop].mode;
+ argmode = TYPE_MODE (TREE_TYPE (arg));
+ if (argmode != opmode)
+ arg = build1 (NOP_EXPR,
+ (*lang_hooks.types.type_for_mode) (opmode, 0), arg);
+ op[nop] = expand_expr (arg, NULL_RTX, opmode, 0);
+ if (! (*insn_data[icode].operand[nop].predicate) (op[nop], opmode))
+ op[nop] = copy_to_mode_reg (opmode, op[nop]);
+ }
+
+ switch (nop)
+ {
+ case 1:
+ pat = (*insn_data[d->icode].genfun) (op[0]);
+ break;
+ case 2:
+ pat = (*insn_data[d->icode].genfun) (op[0], op[1]);
+ break;
+ case 3:
+ pat = (*insn_data[d->icode].genfun) (op[0], op[1], op[2]);
+ break;
+ case 4:
+ pat = (*insn_data[d->icode].genfun) (op[0], op[1], op[2], op[3]);
+ break;
+ }
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+ }
#include "gt-sh.h"
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.153
diff -p -r1.153 sh.h
*** config/sh/sh.h 24 Jun 2002 18:11:55 -0000 1.153
--- config/sh/sh.h 1 Jul 2002 18:54:59 -0000
*************** extern char sh_additional_register_names
*** 924,931 ****
/* Value is 1 if MODE is a supported vector mode. */
#define VECTOR_MODE_SUPPORTED_P(MODE) \
! (TARGET_FPU_ANY \
! && ((MODE) == V2SFmode || (MODE) == V4SFmode || (MODE) == V16SFmode))
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
--- 924,934 ----
/* Value is 1 if MODE is a supported vector mode. */
#define VECTOR_MODE_SUPPORTED_P(MODE) \
! ((TARGET_FPU_ANY \
! && ((MODE) == V2SFmode || (MODE) == V4SFmode || (MODE) == V16SFmode)) \
! || (TARGET_SHMEDIA \
! && ((MODE) == V8QImode || (MODE) == V2HImode || (MODE) == V4HImode \
! || (MODE) == V2SImode)))
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
*************** while (0)
*** 2312,2321 ****
--- 2315,2341 ----
#define EXTRA_CONSTRAINT_T(OP) \
(NON_PIC_REFERENCE_P (OP))
+ /* A zero in any shape or form. */
+ #define EXTRA_CONSTRAINT_U(OP) \
+ ((OP) == const0_rtx \
+ || (GET_CODE (OP) == SUBREG && VECTOR_MODE_SUPPORTED_P(GET_MODE (OP)) \
+ && SUBREG_REG (OP) == const0_rtx && SUBREG_BYTE (OP) == 0) \
+ || GET_CODE (OP) == CONST_VECTOR && zero_vec_operand ((OP), VOIDmode))
+
+ /* Any vector constant we can handle. */
+ #define EXTRA_CONSTRAINT_W(OP) \
+ (GET_CODE (OP) == CONST_VECTOR \
+ && (sh_rep_vec ((OP), VOIDmode) \
+ || (HOST_BITS_PER_WIDE_INT >= 64 \
+ ? sh_const_vec ((OP), VOIDmode) \
+ : sh_1el_vec ((OP), VOIDmode))))
+
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP) \
: (C) == 'S' ? EXTRA_CONSTRAINT_S (OP) \
: (C) == 'T' ? EXTRA_CONSTRAINT_T (OP) \
+ : (C) == 'U' ? EXTRA_CONSTRAINT_U (OP) \
+ : (C) == 'W' ? EXTRA_CONSTRAINT_W (OP) \
: 0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
*************** while (0)
*** 2669,2674 ****
--- 2689,2696 ----
case CONST_INT: \
if (TARGET_SHMEDIA) \
{ \
+ if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
+ return 0; \
if (CONST_OK_FOR_J (INTVAL (RTX))) \
return COSTS_N_INSNS (1); \
else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
*************** extern int current_function_interrupt;
*** 3188,3194 ****
extern struct rtx_def *sp_switch;
extern int rtx_equal_function_value_matters;
- extern struct rtx_def *fpscr_rtx;
/* Instructions with unfilled delay slots take up an
--- 3210,3215 ----
*************** extern struct rtx_def *fpscr_rtx;
*** 3200,3222 ****
/* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"binary_float_operator", {PLUS, MULT}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fpscr_operand", {REG}}, \
{"fpul_operand", {REG}}, \
{"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \
{"general_movdst_operand", {SUBREG, REG, MEM}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"noncommutative_float_operator", {MINUS, DIV}}, \
{"shmedia_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{"target_reg_operand", {SUBREG, REG}}, \
! {"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF}}, \
{"register_operand", {SUBREG, REG}}, \
! {"symbol_ref_operand", {SYMBOL_REF}},
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
--- 3221,3252 ----
/* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \
+ {"and_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
+ {"arith_reg_dest", {SUBREG, REG}}, \
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"binary_float_operator", {PLUS, MULT}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
+ {"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
+ {"extend_reg_or_0_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
{"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fpscr_operand", {REG}}, \
{"fpul_operand", {REG}}, \
{"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \
{"general_movdst_operand", {SUBREG, REG, MEM}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
+ {"mextr_bit_offset", {CONST_INT}}, \
{"noncommutative_float_operator", {MINUS, DIV}}, \
{"shmedia_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{"target_reg_operand", {SUBREG, REG}}, \
! {"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
{"register_operand", {SUBREG, REG}}, \
! {"sh_const_vec", {CONST_VECTOR}}, \
! {"sh_1el_vec", {CONST_VECTOR, PARALLEL}}, \
! {"sh_rep_vec", {CONST_VECTOR, PARALLEL}}, \
! {"symbol_ref_operand", {SYMBOL_REF}}, \
! {"zero_vec_operand", {CONST_VECTOR}},
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.106
diff -p -r1.106 sh.md
*** config/sh/sh.md 24 Jun 2002 20:08:16 -0000 1.106
--- config/sh/sh.md 1 Jul 2002 18:54:59 -0000
***************
*** 129,134 ****
--- 129,140 ----
(UNSPEC_CALLER 10)
(UNSPEC_GOTPLT 11)
(UNSPEC_ICACHE 12)
+ (UNSPEC_INIT_TRAMP 13)
+ (UNSPEC_FCOSA 14)
+ (UNSPEC_FSRRA 15)
+ (UNSPEC_FSINA 16)
+ (UNSPEC_NSB 17)
+ (UNSPEC_ALLOCO 18)
;; These are used with unspec_volatile.
(UNSPECV_BLOCKAGE 0)
***************
*** 197,203 ****
;; nil no-op move, will be deleted.
(define_attr "type"
! "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pt,ptabs,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,nil"
(const_string "other"))
;; We define a new attribute namely "insn_class".We use
--- 203,209 ----
;; nil no-op move, will be deleted.
(define_attr "type"
! "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt,ptabs,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
(const_string "other"))
;; We define a new attribute namely "insn_class".We use
***************
*** 1984,1997 ****
}
}")
! (define_insn "anddi3"
! [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
! (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
! (match_operand:DI 2 "logical_operand" "r,P")))]
"TARGET_SHMEDIA"
"@
and %1, %2, %0
! andi %1, %2, %0")
(define_insn "*andcdi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
--- 1990,2015 ----
}
}")
! (define_insn_and_split "anddi3"
! [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
! (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
! (match_operand:DI 2 "and_operand" "r,P,n")))]
"TARGET_SHMEDIA"
"@
and %1, %2, %0
! andi %1, %2, %0
! #"
! "reload_completed
! && ! logical_operand (operands[2], DImode)"
! [(const_int 0)]
! "
! {
! if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
! emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
! else
! emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
! DONE;
! }")
(define_insn "*andcdi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
***************
*** 3626,3653 ****
&& GET_CODE (operands[1]) == CONST_INT
&& ! CONST_OK_FOR_J (INTVAL (operands[1]))"
[(set (match_dup 0) (match_dup 2))
! (set (match_dup 0)
! (ior:DI (ashift:DI (match_dup 0) (const_int 16))
! (zero_extend:DI (truncate:HI (match_dup 1)))))]
"
{
! unsigned HOST_WIDE_INT low = INTVAL (operands[1]);
! unsigned HOST_WIDE_INT val = low;
unsigned HOST_WIDE_INT sign;
/* Sign-extend the 16 least-significant bits. */
! val &= 0xffff;
! val ^= 0x8000;
! val -= 0x8000;
! operands[1] = GEN_INT (val);
/* Arithmetic shift right the word by 16 bits. */
! low >>= 16;
sign = 1;
sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
! low ^= sign;
! low -= sign;
! operands[2] = GEN_INT (low);
}")
(define_split
--- 3644,3738 ----
&& GET_CODE (operands[1]) == CONST_INT
&& ! CONST_OK_FOR_J (INTVAL (operands[1]))"
[(set (match_dup 0) (match_dup 2))
! (match_dup 1)]
"
{
! unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
! unsigned HOST_WIDE_INT low = val;
! unsigned HOST_WIDE_INT high = val;
unsigned HOST_WIDE_INT sign;
+ unsigned HOST_WIDE_INT val2 = val ^ (val-1);
/* Sign-extend the 16 least-significant bits. */
! low &= 0xffff;
! low ^= 0x8000;
! low -= 0x8000;
/* Arithmetic shift right the word by 16 bits. */
! high >>= 16;
sign = 1;
sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
! high ^= sign;
! high -= sign;
! do
! {
! /* If we can't generate the constant with a two-insn movi / shori
! sequence, try some other strategies. */
! if (! CONST_OK_FOR_J (high))
! {
! /* Try constant load / left shift. We know VAL != 0. */
! val2 = val ^ (val-1);
! if (val2 > 0x1ffff)
! {
! int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
!
! if (CONST_OK_FOR_J (val >> trailing_zeroes)
! || (! CONST_OK_FOR_J (high >> 16)
! && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
! {
! val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
! operands[1] = gen_ashldi3_media (operands[0], operands[0],
! GEN_INT (trailing_zeroes));
! break;
! }
! }
! /* Try constant load / right shift. */
! val2 = (val >> 15) + 1;
! if (val2 == (val2 & -val2))
! {
! int shift = 49 - exact_log2 (val2);
!
! val2 = trunc_int_for_mode (val << shift, DImode);
! if (CONST_OK_FOR_J (val2))
! {
! operands[1] = gen_lshrdi3_media (operands[0], operands[0],
! GEN_INT (shift));
! break;
! }
! }
! /* Try mperm.w . */
! val2 = val & 0xffff;
! if ((val >> 16 & 0xffff) == val2
! && (val >> 32 & 0xffff) == val2
! && (val >> 48 & 0xffff) == val2)
! {
! val2 = (HOST_WIDE_INT) val >> 48;
! operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
! operands[1] = gen_mperm_w0 (operands[1], operands[1]);
! break;
! }
! /* Try movi / mshflo.l */
! val2 = (HOST_WIDE_INT) val >> 32;
! if (val2 == trunc_int_for_mode (val, SImode))
! {
! operands[1] = gen_mshflo_l_di (operands[0], operands[0],
! operands[0]);
! break;
! }
! /* Try movi / mshflo.l w/ r63. */
! val2 = val + ((HOST_WIDE_INT) -1 << 32);
! if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
! {
! operands[1] = gen_mshflo_l_di (operands[0], operands[0],
! GEN_INT (0));
! break;
! }
! }
! val2 = high;
! operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
! }
! while (0);
! operands[2] = GEN_INT (val2);
}")
(define_split
***************
*** 3690,3696 ****
operands[2] = immed_double_const (low, high, DImode);
}")
! (define_insn "*shori_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
(ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
(const_int 16))
--- 3775,3781 ----
operands[2] = immed_double_const (low, high, DImode);
}")
! (define_insn "shori_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
(ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
(const_int 16))
***************
*** 7507,7513 ****
(define_split
[(set (reg:PSI FPSCR_REG)
! (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
"TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(set (match_dup 0) (match_dup 0))]
"
--- 7592,7598 ----
(define_split
[(set (reg:PSI FPSCR_REG)
! (mem:PSI (match_operand:SI 0 "register_operand" "")))]
"TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(set (match_dup 0) (match_dup 0))]
"
***************
*** 7521,7527 ****
(define_split
[(set (reg:PSI FPSCR_REG)
! (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
"TARGET_SH4"
[(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
"
--- 7606,7612 ----
(define_split
[(set (reg:PSI FPSCR_REG)
! (mem:PSI (match_operand:SI 0 "register_operand" "")))]
"TARGET_SH4"
[(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
"
***************
*** 8645,8650 ****
--- 8730,9855 ----
"TARGET_SH1"
"mov.l @r15+,r15\;mov.l @r15+,r0"
[(set_attr "length" "4")])
+
+ ;; Integer vector moves
+
+ (define_expand "movv8qi"
+ [(set (match_operand:V8QI 0 "general_movdst_operand" "")
+ (match_operand:V8QI 1 "general_movsrc_operand" ""))]
+ "TARGET_SHMEDIA"
+ "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
+
+ (define_insn "movv8qi_i"
+ [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
+ (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
+ "TARGET_SHMEDIA
+ && (register_operand (operands[0], V8QImode)
+ || register_operand (operands[1], V8QImode))"
+ "@
+ add %1, r63, %0
+ movi %1, %0
+ #
+ ld%M1.q %m1, %0
+ st%M0.q %m0, %1"
+ [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
+ (set_attr "length" "4,4,16,4,4")])
+
+ (define_split
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "")
+ (subreg:V8QI (const_int 0) 0))]
+ "TARGET_SHMEDIA"
+ [(set (match_dup 0)
+ (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)]))])
+
+ (define_split
+ [(set (match_operand 0 "arith_reg_dest" "")
+ (match_operand 1 "sh_rep_vec" ""))]
+ "TARGET_SHMEDIA && reload_completed
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
+ && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
+ && (XVECEXP (operands[1], 0, 0) != const0_rtx
+ || XVECEXP (operands[1], 0, 1) != const0_rtx)"
+ [(set (match_dup 0) (match_dup 1))
+ (match_dup 2)]
+ "
+ {
+ int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
+ rtx elt1 = XVECEXP (operands[1], 0, 1);
+
+ if (unit_size > 2)
+ operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
+ else
+ operands[2] = gen_mperm_w0 (operands[0], operands[0]);
+ operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
+ operands[1] = XVECEXP (operands[1], 0, 0);
+ if (unit_size < 2)
+ {
+ if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
+ operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
+ ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
+ : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
+ else
+ {
+ operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
+ operands[1]
+ = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
+ }
+ }
+ }")
+
+ (define_split
+ [(set (match_operand 0 "arith_reg_dest" "")
+ (match_operand 1 "sh_const_vec" ""))]
+ "TARGET_SHMEDIA && reload_completed
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
+ && XVECEXP (operands[1], 0, 0) != const0_rtx
+ && (HOST_BITS_PER_WIDE_INT >= 64
+ || HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (GET_MODE (operands[0]))
+ || sh_1el_vec (operands[1], VOIDmode))"
+ [(set (match_dup 0) (match_dup 1))]
+ "
+ {
+ rtx v = operands[1];
+ enum machine_mode new_mode
+ = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
+
+ operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
+ operands[1]
+ = simplify_subreg (new_mode, operands[1], GET_MODE (operands[0]), 0);
+ }")
+
+ (define_expand "movv2hi"
+ [(set (match_operand:V2HI 0 "general_movdst_operand" "")
+ (match_operand:V2HI 1 "general_movsrc_operand" ""))]
+ "TARGET_SHMEDIA"
+ "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
+
+ (define_insn "movv2hi_i"
+ [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
+ (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
+ "TARGET_SHMEDIA
+ && (register_operand (operands[0], V2HImode)
+ || register_operand (operands[1], V2HImode))"
+ "@
+ addz.l %1, r63, %0
+ movi %1, %0
+ #
+ ld%M1.l %m1, %0
+ st%M0.l %m0, %1"
+ [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
+ (set_attr "length" "4,4,16,4,4")])
+
+ (define_expand "movv4hi"
+ [(set (match_operand:V4HI 0 "general_movdst_operand" "")
+ (match_operand:V4HI 1 "general_movsrc_operand" ""))]
+ "TARGET_SHMEDIA"
+ "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
+
+ (define_insn "movv4hi_i"
+ [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
+ (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
+ "TARGET_SHMEDIA
+ && (register_operand (operands[0], V4HImode)
+ || register_operand (operands[1], V4HImode))"
+ "@
+ add %1, r63, %0
+ movi %1, %0
+ #
+ ld%M1.q %m1, %0
+ st%M0.q %m0, %1"
+ [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
+ (set_attr "length" "4,4,16,4,4")])
+
+ (define_expand "movv2si"
+ [(set (match_operand:V2SI 0 "general_movdst_operand" "")
+ (match_operand:V2SI 1 "general_movsrc_operand" ""))]
+ "TARGET_SHMEDIA"
+ "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
+
+ (define_insn "movv2si_i"
+ [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
+ (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
+ "TARGET_SHMEDIA
+ && (register_operand (operands[0], V2SImode)
+ || register_operand (operands[1], V2SImode))"
+ "@
+ add %1, r63, %0
+ movi %1, %0
+ #
+ ld%M1.q %m1, %0
+ st%M0.q %m0, %1"
+ [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
+ (set_attr "length" "4,4,16,4,4")])
+
+ ;; Multimedia Intrinsics
+
+ (define_insn "absv2si2"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mabs.l %1, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "absv4hi2"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mabs.w %1, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "addv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
+ (match_operand:V2SI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "madd.l %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "addv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
+ (match_operand:V4HI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "madd.w %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "ssaddv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
+ (match_operand:V2SI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "madds.l %1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "usaddv8qi3"
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
+ (match_operand:V8QI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "madds.ub %1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "ssaddv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
+ (match_operand:V4HI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "madds.w %1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "negcmpeqv8qi"
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcmpeq.b %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "negcmpeqv2si"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
+ (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcmpeq.l %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "negcmpeqv4hi"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
+ (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcmpeq.w %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "negcmpgtuv8qi"
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcmpgt.ub %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "negcmpgtv2si"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
+ (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcmpgt.l %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "negcmpgtv4hi"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
+ (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcmpgt.w %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "mcmv"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_operand" "r"))
+ (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
+ (not:DI (match_dup 2)))))]
+ "TARGET_SHMEDIA"
+ "mcmv %N1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mcnvs_lw"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_concat:V4HI
+ (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
+ (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcnvs.lw %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "mcnvs_wb"
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (vec_concat:V8QI
+ (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
+ (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcnvs.wb %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "mcnvs_wub"
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (vec_concat:V8QI
+ (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
+ (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mcnvs.wub %N1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "mextr_rl"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:HI 3 "mextr_bit_offset" "i"))
+ (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (match_operand:HI 4 "mextr_bit_offset" "i"))))]
+ "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
+ "*
+ {
+ static char templ[16];
+
+ sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
+ (int) INTVAL (operands[3]) >> 3);
+ return templ;
+ }"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "*mextr_lr"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:HI 3 "mextr_bit_offset" "i"))
+ (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (match_operand:HI 4 "mextr_bit_offset" "i"))))]
+ "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
+ "*
+ {
+ static char templ[16];
+
+ sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
+ (int) INTVAL (operands[4]) >> 3);
+ return templ;
+ }"
+ [(set_attr "type" "arith_media")])
+
+ ; mextrN can be modelled with vec_select / vec_concat, but the selection
+ ; vector then varies depending on endianness.
+ (define_expand "mextr1"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (1 * 8), GEN_INT (7 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mextr2"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (2 * 8), GEN_INT (6 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mextr3"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (3 * 8), GEN_INT (5 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mextr4"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (4 * 8), GEN_INT (4 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mextr5"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (5 * 8), GEN_INT (3 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mextr6"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (6 * 8), GEN_INT (2 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mextr7"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ GEN_INT (7 * 8), GEN_INT (1 * 8)));
+ DONE;
+ }")
+
+ (define_expand "mmacfx_wl"
+ [(match_operand:V2SI 0 "arith_reg_dest" "")
+ (match_operand:V2HI 1 "extend_reg_operand" "")
+ (match_operand:V2HI 2 "extend_reg_operand" "")
+ (match_operand:V2SI 3 "arith_reg_operand" "")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
+ operands[1], operands[2]));
+ DONE;
+ }")
+
+ (define_insn "mmacfx_wl_i"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ss_plus:V2SI
+ (match_operand:V2SI 1 "arith_reg_operand" "0")
+ (ss_truncate:V2SI
+ (ashift:V2DI
+ (sign_extend:V2DI
+ (mult:V2SI
+ (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
+ (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
+ (const_int 1)))))]
+ "TARGET_SHMEDIA"
+ "mmacfx.wl %2, %3, %0"
+ [(set_attr "type" "mac_media")])
+
+ (define_expand "mmacnfx_wl"
+ [(match_operand:V2SI 0 "arith_reg_dest" "")
+ (match_operand:V2HI 1 "extend_reg_operand" "")
+ (match_operand:V2HI 2 "extend_reg_operand" "")
+ (match_operand:V2SI 3 "arith_reg_operand" "")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
+ operands[1], operands[2]));
+ DONE;
+ }")
+
+ (define_insn "mmacnfx_wl_i"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ss_minus:V2SI
+ (match_operand:V2SI 1 "arith_reg_operand" "0")
+ (ss_truncate:V2SI
+ (ashift:V2DI
+ (sign_extend:V2DI
+ (mult:V2SI
+ (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
+ (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
+ (const_int 1)))))]
+ "TARGET_SHMEDIA"
+ "mmacnfx.wl %2, %3, %0"
+ [(set_attr "type" "mac_media")])
+
+ (define_insn "mulv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
+ (match_operand:V2SI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mmul.l %1, %2, %0"
+ [(set_attr "type" "d2mpy_media")])
+
+ (define_insn "mulv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (match_operand:V4HI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mmul.w %1, %2, %0"
+ [(set_attr "type" "dmpy_media")])
+
+ (define_insn "mmulfx_l"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ss_truncate:V2SI
+ (ashiftrt:V2DI
+ (mult:V2DI
+ (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
+ (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
+ (const_int 31))))]
+ "TARGET_SHMEDIA"
+ "mmulfx.l %1, %2, %0"
+ [(set_attr "type" "d2mpy_media")])
+
+ (define_insn "mmulfx_w"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ss_truncate:V4HI
+ (ashiftrt:V4SI
+ (mult:V4SI
+ (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
+ (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
+ (const_int 15))))]
+ "TARGET_SHMEDIA"
+ "mmulfx.w %1, %2, %0"
+ [(set_attr "type" "dmpy_media")])
+
+ (define_insn "mmulfxrp_w"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ss_truncate:V4HI
+ (ashiftrt:V4SI
+ (plus:V4SI
+ (mult:V4SI
+ (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
+ (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
+ (const_int 16384))
+ (const_int 15))))]
+ "TARGET_SHMEDIA"
+ "mmulfxrp.w %1, %2, %0"
+ [(set_attr "type" "dmpy_media")])
+
+ (define_expand "mmulhi_wl"
+ [(match_operand:V2SI 0 "arith_reg_dest" "")
+ (match_operand:V4HI 1 "arith_reg_operand" "")
+ (match_operand:V4HI 2 "arith_reg_operand" "")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
+ (operands[0], operands[1], operands[2]));
+ DONE;
+ }")
+
+ (define_expand "mmullo_wl"
+ [(match_operand:V2SI 0 "arith_reg_dest" "")
+ (match_operand:V4HI 1 "arith_reg_operand" "")
+ (match_operand:V4HI 2 "arith_reg_operand" "")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
+ (operands[0], operands[1], operands[2]));
+ DONE;
+ }")
+
+ (define_insn "mmul23_wl"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (vec_select:V2SI
+ (mult:V4SI
+ (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
+ (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
+ (const_vector [(const_int 2) (const_int 3)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mmulhi.wl %1, %2, %0\"
+ : \"mmullo.wl %1, %2, %0\");"
+ [(set_attr "type" "dmpy_media")])
+
+ (define_insn "mmul01_wl"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (vec_select:V2SI
+ (mult:V4SI
+ (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
+ (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
+ (const_vector [(const_int 0) (const_int 1)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mmullo.wl %1, %2, %0\"
+ : \"mmulhi.wl %1, %2, %0\");"
+ [(set_attr "type" "dmpy_media")])
+
+ (define_expand "mmulsum_wq"
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:V4HI 1 "arith_reg_operand" "")
+ (match_operand:V4HI 2 "arith_reg_operand" "")
+ (match_operand:DI 3 "arith_reg_operand" "")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
+ operands[1], operands[2]));
+ DONE;
+ }")
+
+ (define_insn "mmulsum_wq_i"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
+ (plus:DI
+ (plus:DI
+ (vec_select:DI
+ (mult:V4DI
+ (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
+ (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
+ (const_vector [(const_int 0)]))
+ (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
+ (sign_extend:V4DI (match_dup 3)))
+ (const_vector [(const_int 1)])))
+ (plus:DI
+ (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
+ (sign_extend:V4DI (match_dup 3)))
+ (const_vector [(const_int 2)]))
+ (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
+ (sign_extend:V4DI (match_dup 3)))
+ (const_vector [(const_int 3)]))))))]
+ "TARGET_SHMEDIA"
+ "mmulsum.wq %2, %3, %0"
+ [(set_attr "type" "mac_media")])
+
+ (define_expand "mperm_w"
+ [(match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ ; This use of vec_select isn't exactly correct according to rtl.texi
+ ; (because not constant), but it seems a straightforward extension.
+ (define_insn "mperm_w_little"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_select:V4HI
+ (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (parallel
+ [(zero_extract (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
+ (const_int 2) (const_int 0))
+ (zero_extract (match_dup 2) (const_int 2) (const_int 2))
+ (zero_extract (match_dup 2) (const_int 2) (const_int 4))
+ (zero_extract (match_dup 2) (const_int 2) (const_int 6))])))]
+ "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
+ "mperm.w %1, %N2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mperm_w_big"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_select:V4HI
+ (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (parallel
+ [(zero_extract (not:QI (match_operand:QI 2
+ "extend_reg_or_0_operand" "rU"))
+ (const_int 2) (const_int 0))
+ (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 2))
+ (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 4))
+ (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 6))])))]
+ "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
+ "mperm.w %1, %N2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mperm_w0"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_duplicate:V4HI (truncate:HI (match_operand 1
+ "extend_reg_operand" "r"))))]
+ "TARGET_SHMEDIA"
+ "mperm.w %1, r63, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_expand "msad_ubq"
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
+ (match_operand:DI 3 "arith_reg_operand" "")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn (gen_msad_ubq_i (operands[0], operands[3],
+ operands[1], operands[2]));
+ DONE;
+ }")
+
+ (define_insn "msad_ubq_i"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (plus:DI
+ (plus:DI
+ (plus:DI
+ (plus:DI
+ (match_operand:DI 1 "arith_reg_operand" "0")
+ (abs:DI (vec_select:DI
+ (minus:V8DI
+ (zero_extend:V8DI
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
+ (zero_extend:V8DI
+ (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
+ (const_vector [(const_int 0)]))))
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 1)]))))
+ (plus:DI
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 2)])))
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 3)])))))
+ (plus:DI
+ (plus:DI
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 4)])))
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 5)]))))
+ (plus:DI
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 6)])))
+ (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
+ (zero_extend:V8DI (match_dup 3)))
+ (const_vector [(const_int 7)])))))))]
+ "TARGET_SHMEDIA"
+ "msad.ubq %N2, %N3, %0"
+ [(set_attr "type" "mac_media")])
+
+ (define_insn "mshalds_l"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ss_truncate:V2SI
+ (ashift:V2DI
+ (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
+ (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
+ (const_int 31)))))]
+ "TARGET_SHMEDIA"
+ "mshalds.l %1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "mshalds_w"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ss_truncate:V4HI
+ (ashift:V4SI
+ (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
+ (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
+ (const_int 15)))))]
+ "TARGET_SHMEDIA"
+ "mshalds.w %1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "ashrv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mshard.l %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "ashrv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mshard.w %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mshards_q"
+ [(set (match_operand:HI 0 "arith_reg_dest" "=r")
+ (ss_truncate:HI
+ (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
+ "TARGET_SHMEDIA"
+ "mshards.q %1, %N2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_expand "mshfhi_b"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ (define_expand "mshflo_b"
+ [(match_operand:V8QI 0 "arith_reg_dest" "")
+ (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ (define_insn "mshf4_b"
+ [(set
+ (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (vec_select:V8QI
+ (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
+ (const_vector [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
+ (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mshfhi.b %N1, %N2, %0\"
+ : \"mshflo.b %N1, %N2, %0\");"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mshf0_b"
+ [(set
+ (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (vec_select:V8QI
+ (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
+ (const_vector [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
+ (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mshflo.b %N1, %N2, %0\"
+ : \"mshfhi.b %N1, %N2, %0\");"
+ [(set_attr "type" "arith_media")])
+
+ (define_expand "mshfhi_l"
+ [(match_operand:V2SI 0 "arith_reg_dest" "")
+ (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ (define_expand "mshflo_l"
+ [(match_operand:V2SI 0 "arith_reg_dest" "")
+ (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ (define_insn "mshf4_l"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (vec_select:V2SI
+ (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
+ (const_vector [(const_int 1) (const_int 3)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mshfhi.l %N1, %N2, %0\"
+ : \"mshflo.l %N1, %N2, %0\");"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mshf0_l"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (vec_select:V2SI
+ (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
+ (const_vector [(const_int 0) (const_int 2)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mshflo.l %N1, %N2, %0\"
+ : \"mshfhi.l %N1, %N2, %0\");"
+ [(set_attr "type" "arith_media")])
+
+ (define_expand "mshfhi_w"
+ [(match_operand:V4HI 0 "arith_reg_dest" "")
+ (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ (define_expand "mshflo_w"
+ [(match_operand:V4HI 0 "arith_reg_dest" "")
+ (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
+ "TARGET_SHMEDIA"
+ "
+ {
+ emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
+ (operands[0], operands[1], operands[2]));
+ }")
+
+ (define_insn "mshf4_w"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_select:V4HI
+ (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
+ (const_vector [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mshfhi.w %N1, %N2, %0\"
+ : \"mshflo.w %N1, %N2, %0\");"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mshf0_w"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_select:V4HI
+ (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
+ (const_vector [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
+ "TARGET_SHMEDIA"
+ "* return (TARGET_LITTLE_ENDIAN
+ ? \"mshflo.w %N1, %N2, %0\"
+ : \"mshfhi.w %N1, %N2, %0\");"
+ [(set_attr "type" "arith_media")])
+
+ /* These are useful to expand ANDs and as combiner patterns. */
+ (define_insn "mshfhi_l_di"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (const_int 32))
+ (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (const_int -4294967296))))]
+ "TARGET_SHMEDIA"
+ "mshfhi.l %N1, %N2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "*mshfhi_l_di_rev"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (const_int -4294967296))
+ (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (const_int 32))))]
+ "TARGET_SHMEDIA"
+ "mshfhi.l %N2, %N1, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "mshflo_l_di"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (const_int 4294967295))
+ (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (const_int 32))))]
+
+ "TARGET_SHMEDIA"
+ "mshflo.l %N1, %N2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "*mshflo_l_di_rev"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (const_int 32))
+ (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (const_int 4294967295))))]
+
+ "TARGET_SHMEDIA"
+ "mshflo.l %N2, %N1, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "*mshflo_l_di_x"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand" "rU"))
+ (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (const_int 32))))]
+
+ "TARGET_SHMEDIA"
+ "mshflo.l %N1, %N2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "*mshflo_l_di_x_rev"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (const_int 32))
+ (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
+
+ "TARGET_SHMEDIA"
+ "mshflo.l %N2, %N1, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "ashlv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mshlld.l %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "ashlv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mshlld.w %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "lshrv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mshlrd.l %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "lshrv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "mshlrd.w %1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "subv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V2SI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "msub.l %N1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "subv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V4HI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "msub.w %N1, %2, %0"
+ [(set_attr "type" "arith_media")])
+
+ (define_insn "sssubv2si3"
+ [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
+ (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V2SI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "msubs.l %N1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "ussubv8qi3"
+ [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
+ (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
+ (match_operand:V8QI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "msubs.ub %1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ (define_insn "sssubv4hi3"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:V4HI 2 "arith_reg_operand" "r")))]
+ "TARGET_SHMEDIA"
+ "msubs.w %N1, %2, %0"
+ [(set_attr "type" "mcmp_media")])
+
+ ;; Floating Point Intrinsics
+
+ (define_insn "fcosa_s"
+ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
+ (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
+ UNSPEC_FCOSA))]
+ "TARGET_SHMEDIA"
+ "fcosa.s %1, %0"
+ [(set_attr "type" "atrans_media")])
+
+ (define_insn "fsina_s"
+ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
+ (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
+ UNSPEC_FSINA))]
+ "TARGET_SHMEDIA"
+ "fsina.s %1, %0"
+ [(set_attr "type" "atrans_media")])
+
+ (define_insn "fipr"
+ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
+ (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
+ "fp_arith_reg_operand" "f")
+ (match_operand:V4SF 2
+ "fp_arith_reg_operand" "f"))
+ (const_vector [(const_int 0)]))
+ (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
+ (const_vector [(const_int 1)])))
+ (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
+ (const_vector [(const_int 2)]))
+ (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
+ (const_vector [(const_int 3)])))))]
+ "TARGET_SHMEDIA"
+ "fipr %1, %2, %0"
+ [(set_attr "type" "fparith_media")])
+
+ (define_insn "fsrra_s"
+ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
+ (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
+ UNSPEC_FSRRA))]
+ "TARGET_SHMEDIA"
+ "fsrra.s %1, %0"
+ [(set_attr "type" "atrans_media")])
+
+ (define_insn "ftrv"
+ [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
+ (plus:V4SF
+ (plus:V4SF
+ (mult:V4SF
+ (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
+ (const_vector [(const_int 0) (const_int 5)
+ (const_int 10) (const_int 15)]))
+ (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
+ (mult:V4SF
+ (vec_select:V4SF (match_dup 1)
+ (const_vector [(const_int 4) (const_int 9)
+ (const_int 14) (const_int 3)]))
+ (vec_select:V4SF (match_dup 2)
+ (const_vector [(const_int 1) (const_int 2)
+ (const_int 3) (const_int 0)]))))
+ (plus:V4SF
+ (mult:V4SF
+ (vec_select:V4SF (match_dup 1)
+ (const_vector [(const_int 8) (const_int 13)
+ (const_int 2) (const_int 7)]))
+ (vec_select:V4SF (match_dup 2)
+ (const_vector [(const_int 2) (const_int 3)
+ (const_int 0) (const_int 1)])))
+ (mult:V4SF
+ (vec_select:V4SF (match_dup 1)
+ (const_vector [(const_int 12) (const_int 1)
+ (const_int 6) (const_int 11)]))
+ (vec_select:V4SF (match_dup 2)
+ (const_vector [(const_int 3) (const_int 0)
+ (const_int 1) (const_int 2)]))))))]
+ "TARGET_SHMEDIA"
+ "ftrv %1, %2, %0"
+ [(set_attr "type" "fparith_media")])
;; The following description models the
;; SH4 pipeline using the DFA based scheduler.
More information about the Gcc-patches
mailing list