#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 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);
+
\f
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
#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;
\f
/* Print the operand address in x to the stream. */
'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. */
}
break;
+ case 'N':
+ if (x == const0_rtx)
+ {
+ fprintf ((stream), "r63");
+ break;
+ }
+ goto default_output;
case 'u':
if (GET_CODE (x) == CONST_INT)
{
}
/* Fall through. */
+ default_output:
default:
switch (GET_CODE (x))
{
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;
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
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;
+}
\f
/* Return the destination address of a branch. */
/* 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 (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
/* 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)
+static rtx
+mark_constant_pool_use (x)
rtx x;
{
rtx insn, lab, pattern;
return str;
}
+\f
+/* 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"
(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)
;; 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"
+ "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
}
}")
-(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")))]
+(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")
+ 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")
&& 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)))))]
+ (match_dup 1)]
"
{
- unsigned HOST_WIDE_INT low = INTVAL (operands[1]);
- unsigned HOST_WIDE_INT val = low;
+ 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. */
- val &= 0xffff;
- val ^= 0x8000;
- val -= 0x8000;
- operands[1] = GEN_INT (val);
+ low &= 0xffff;
+ low ^= 0x8000;
+ low -= 0x8000;
/* Arithmetic shift right the word by 16 bits. */
- low >>= 16;
+ high >>= 16;
sign = 1;
sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
- low ^= sign;
- low -= sign;
- operands[2] = GEN_INT (low);
+ 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
operands[2] = immed_double_const (low, high, DImode);
}")
-(define_insn "*shori_media"
+(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))
(define_split
[(set (reg:PSI FPSCR_REG)
- (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
+ (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))]
"
(define_split
[(set (reg:PSI FPSCR_REG)
- (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
+ (mem:PSI (match_operand:SI 0 "register_operand" "")))]
"TARGET_SH4"
[(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
"
"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.
;; The DFA based description is better way to model