OSDN Git Service

* sh.c (langhooks.h): Include.
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Jul 2002 19:41:54 +0000 (19:41 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Jul 2002 19:41:54 +0000 (19:41 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55147 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md

index 84b62a9..a4d02b4 100644 (file)
@@ -1,3 +1,52 @@
+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.
+
 2002-07-01  Aldy Hernandez  <aldyh@redhat.com>
 
         * tree.c (build_function_type_list): Update function comment.
index a489dcf..429eda6 100644 (file)
@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA.  */
 #include "target.h"
 #include "target-def.h"
 #include "real.h"
+#include "langhooks.h"
 
 int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
 
@@ -204,6 +205,10 @@ static bool sh_ms_bitfield_layout_p PARAMS ((tree));
 
 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
@@ -247,6 +252,11 @@ static const char *sh_strip_name_encoding PARAMS ((const char *));
 #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.  */
@@ -320,6 +330,7 @@ print_operand_address (stream, x)
    '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.  */
@@ -422,6 +433,13 @@ print_operand (stream, x, code)
        }
       break;
 
+    case 'N':
+      if (x == const0_rtx)
+       {
+         fprintf ((stream), "r63");
+         break;
+       }
+      goto default_output;
     case 'u':
       if (GET_CODE (x) == CONST_INT)
         {
@@ -430,6 +448,7 @@ print_operand (stream, x, code)
        }
       /* Fall through.  */
 
+    default_output:
     default:
       switch (GET_CODE (x))
        {
@@ -5846,6 +5865,20 @@ arith_reg_operand (op, mode)
   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;
@@ -5948,6 +5981,25 @@ logical_operand (op, mode)
   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
@@ -6129,6 +6181,135 @@ target_operand (op, mode)
   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.  */
    
@@ -6446,8 +6627,8 @@ sh_insn_length_adjustment (insn)
   /* 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
@@ -6588,7 +6769,8 @@ legitimize_pic_address (orig, mode, reg)
 
 /* 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;
@@ -6848,4 +7030,299 @@ sh_strip_name_encoding (str)
   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"
index faf030c..abf9945 100644 (file)
@@ -924,8 +924,11 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 
 /* 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_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.
@@ -2312,10 +2315,27 @@ while (0)
 #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)
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@@ -2669,6 +2689,8 @@ while (0)
   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)) \
@@ -3188,7 +3210,6 @@ extern int current_function_interrupt;
 extern struct rtx_def *sp_switch;
 
 extern int rtx_equal_function_value_matters;
-extern struct rtx_def *fpscr_rtx;
 
 \f
 /* Instructions with unfilled delay slots take up an
@@ -3200,23 +3221,32 @@ extern struct rtx_def *fpscr_rtx;
 \f
 /* 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}},            \
+  {"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
   {"register_operand", {SUBREG, REG}},                                 \
-  {"symbol_ref_operand", {SYMBOL_REF}},
+  {"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 d450893..8303c96 100644 (file)
   (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