basic multimedia patch applied to SH gcc port

Joern Rennecke joern.rennecke@superh.com
Mon Jul 1 12:44:00 GMT 2002


Tested for sh64-elf.

-- 
--------------------------
SuperH
2430 Aztec West / Almondsbury / BRISTOL / BS32 4AQ
T:+44 1454 462330
-------------- next part --------------
Mon Jul  1 19:55:17 2002  J"orn Rennecke <joern.rennecke@superh.com>

	* sh.c (langhooks.h): Include.
	(sh_init_builtins, sh_media_init_builtins): New functions.
	(sh_expand_builtin, arith_reg_dest,and_operand): Likewise.
	(mextr_bit_offset, extend_reg_operand, zero_vec_operand): Likewise.
	(sh_rep_vec, sh_1el_vec, sh_const_vec): Likewise.
	(builtin_description): New struct tag.
	(signature_args, bdesc): New arrays.
	(TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Undef / define.
	(print_operand): Add 'N' modifier.
	* sh.h (VECTOR_MODE_SUPPORTED_P): Add SHmedia vector modes.
	(EXTRA_CONSTRAINT_U, EXTRA_CONSTRAINT_W): New macros.
	(EXTRA_CONSTRAINT): Add 'U' and 'W' cases.
	(CONST_COSTS): Add special case for SHmedia AND.
	(PREDICATE_CODES): Add and_operand, arith_reg_dest,
	extend_reg_operand, extend_reg_or_0_operand, mextr_bit_offset,
	sh_const_vec, sh_1el_vec, sh_rep_vec, zero_vec_operand.
	target_operand can also be const or unspec.
	* sh.md (UNSPEC_INIT_TRAMP, UNSPEC_FCOSA UNSPEC_FSRRA): New constants.
	(UNSPEC_FSINA, UNSPEC_NSB, UNSPEC_ALLOCO): Likewise.
	(attribute type): Add new types.
	(anddi3): Add splitter.
	(movdi_const_16bit+1): Add code to handle vector constants and
	bitmasks efficiently.
	(shori_media): Have generator function made.
	(movv8qi, movv8qi_i, movv8qi_i+1, movv8qi_i+2): New patterns.
	(movv8qi_i+3, movv2hi, movv2hi_i, movv4hi, movv4hi_i): Likewise.
	(movv2si, movv2si_i, absv2si2, absv4hi2, addv2si3, addv4hi3): Likewise.
	(ssaddv2si3, usaddv8qi3, ssaddv4hi3, negcmpeqv8qi): Likewise.
	(negcmpeqv2si, negcmpeqv4hi, negcmpgtuv8qi, negcmpgtv2si): Likewise.
	(negcmpgtv4hi, mcmv, mcnvs_lw, mcnvs_wb, mcnvs_wub): Likewise.
	(mextr_rl, mextr_lr, mextr1, mextr2, mextr3, mextr4, mextr5): Likewise.
	(mextr6, mextr7, mmacfx_wl, mmacfx_wl_i, mmacnfx_wl): Likewise.
	(mmacnfx_wl_i, mulv2si3, mulv4hi3, mmulfx_l, mmulfx_w): Likewise.
	(mmulfxrp_w, mmulhi_wl, mmullo_wl, mmul23_wl, mmul01_wl): Likewise.
	(mmulsum_wq, mmulsum_wq_i, mperm_w, mperm_w_little): LIkewise.
	(mperm_w_big, mperm_w0, msad_ubq, msad_ubq_i, mshalds_l): Likewise.
	(mshalds_w, ashrv2si3, ashrv4hi3, mshards_q, mshfhi_b): Likewise.
	(mshflo_b,  mshf4_b, mshf0_b, mshfhi_l, mshflo_l, mshf4_l): Likewsie.
	(mshf0_l, mshfhi_w, mshflo_w, mshf4_w, mshf0_w, mshfhi_l_di): Likewise.
	(mshfhi_l_di_rev, mshflo_l_di, mshflo_l_di_rev): Likewise.
	(mshflo_l_di_x, mshflo_l_di_x_rev, ashlv2si3, ashlv4hi3): Likewise.
	(lshrv2si3, lshrv4hi3, subv2si3, subv4hi3, sssubv2si3): Likewise.
	(ussubv8qi3, sssubv4hi3, fcosa_s, fsina_s, fipr, fsrra_s): Likewise.
	(ftrv): Likewise.

	(fpu_switch+1, fpu_switch+2): Remove constraint.

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


More information about the Gcc-patches mailing list