Commit c1b92d09 by J"orn Rennecke Committed by Joern Rennecke

sh.c (langhooks.h): Include.

	* 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.

From-SVN: r55147
parent 7098b619
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> 2002-07-01 Aldy Hernandez <aldyh@redhat.com>
* tree.c (build_function_type_list): Update function comment. * tree.c (build_function_type_list): Update function comment.
......
...@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */
#include "target.h" #include "target.h"
#include "target-def.h" #include "target-def.h"
#include "real.h" #include "real.h"
#include "langhooks.h"
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch; int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
...@@ -204,6 +205,10 @@ static bool sh_ms_bitfield_layout_p PARAMS ((tree)); ...@@ -204,6 +205,10 @@ static bool sh_ms_bitfield_layout_p PARAMS ((tree));
static void sh_encode_section_info PARAMS ((tree, int)); static void sh_encode_section_info PARAMS ((tree, int));
static const char *sh_strip_name_encoding PARAMS ((const char *)); 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. */ /* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE #undef TARGET_ATTRIBUTE_TABLE
...@@ -247,6 +252,11 @@ static const char *sh_strip_name_encoding PARAMS ((const char *)); ...@@ -247,6 +252,11 @@ static const char *sh_strip_name_encoding PARAMS ((const char *));
#undef TARGET_STRIP_NAME_ENCODING #undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING sh_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; struct gcc_target targetm = TARGET_INITIALIZER;
/* Print the operand address in x to the stream. */ /* Print the operand address in x to the stream. */
...@@ -320,6 +330,7 @@ print_operand_address (stream, x) ...@@ -320,6 +330,7 @@ print_operand_address (stream, x)
'S' print the MSW of a dp value - changes if in little endian '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. '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'. '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. '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. 'u' prints the lowest 16 bits of CONST_INT, as an unsigned value.
'o' output an operator. */ 'o' output an operator. */
...@@ -422,6 +433,13 @@ print_operand (stream, x, code) ...@@ -422,6 +433,13 @@ print_operand (stream, x, code)
} }
break; break;
case 'N':
if (x == const0_rtx)
{
fprintf ((stream), "r63");
break;
}
goto default_output;
case 'u': case 'u':
if (GET_CODE (x) == CONST_INT) if (GET_CODE (x) == CONST_INT)
{ {
...@@ -430,6 +448,7 @@ print_operand (stream, x, code) ...@@ -430,6 +448,7 @@ print_operand (stream, x, code)
} }
/* Fall through. */ /* Fall through. */
default_output:
default: default:
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
...@@ -5846,6 +5865,20 @@ arith_reg_operand (op, mode) ...@@ -5846,6 +5865,20 @@ arith_reg_operand (op, mode)
return 0; 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 int
fp_arith_reg_operand (op, mode) fp_arith_reg_operand (op, mode)
rtx op; rtx op;
...@@ -5948,6 +5981,25 @@ logical_operand (op, mode) ...@@ -5948,6 +5981,25 @@ logical_operand (op, mode)
return 0; 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. */ /* Nonzero if OP is a floating point value with value 0.0. */
int int
...@@ -6129,6 +6181,135 @@ target_operand (op, mode) ...@@ -6129,6 +6181,135 @@ target_operand (op, mode)
return target_reg_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;
}
/* Return the destination address of a branch. */ /* Return the destination address of a branch. */
...@@ -6446,8 +6627,8 @@ sh_insn_length_adjustment (insn) ...@@ -6446,8 +6627,8 @@ sh_insn_length_adjustment (insn)
/* Instructions with unfilled delay slots take up an extra two bytes for /* Instructions with unfilled delay slots take up an extra two bytes for
the nop in the delay slot. */ the nop in the delay slot. */
if (((GET_CODE (insn) == INSN if (((GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) != USE && GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER) && GET_CODE (PATTERN (insn)) != CLOBBER)
|| GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CALL_INSN
|| (GET_CODE (insn) == JUMP_INSN || (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
...@@ -6588,7 +6769,8 @@ legitimize_pic_address (orig, mode, reg) ...@@ -6588,7 +6769,8 @@ legitimize_pic_address (orig, mode, reg)
/* Mark the use of a constant in the literal table. If the constant /* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */ has multiple labels, make it unique. */
static rtx mark_constant_pool_use (x) static rtx
mark_constant_pool_use (x)
rtx x; rtx x;
{ {
rtx insn, lab, pattern; rtx insn, lab, pattern;
...@@ -6848,4 +7030,299 @@ sh_strip_name_encoding (str) ...@@ -6848,4 +7030,299 @@ sh_strip_name_encoding (str)
return str; 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" #include "gt-sh.h"
...@@ -924,8 +924,11 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \ ...@@ -924,8 +924,11 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
/* Value is 1 if MODE is a supported vector mode. */ /* Value is 1 if MODE is a supported vector mode. */
#define VECTOR_MODE_SUPPORTED_P(MODE) \ #define VECTOR_MODE_SUPPORTED_P(MODE) \
(TARGET_FPU_ANY \ ((TARGET_FPU_ANY \
&& ((MODE) == V2SFmode || (MODE) == V4SFmode || (MODE) == V16SFmode)) && ((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 /* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2. when one has mode MODE1 and one has mode MODE2.
...@@ -2312,10 +2315,27 @@ while (0) ...@@ -2312,10 +2315,27 @@ while (0)
#define EXTRA_CONSTRAINT_T(OP) \ #define EXTRA_CONSTRAINT_T(OP) \
(NON_PIC_REFERENCE_P (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) \ #define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP) \ ((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP) \
: (C) == 'S' ? EXTRA_CONSTRAINT_S (OP) \ : (C) == 'S' ? EXTRA_CONSTRAINT_S (OP) \
: (C) == 'T' ? EXTRA_CONSTRAINT_T (OP) \ : (C) == 'T' ? EXTRA_CONSTRAINT_T (OP) \
: (C) == 'U' ? EXTRA_CONSTRAINT_U (OP) \
: (C) == 'W' ? EXTRA_CONSTRAINT_W (OP) \
: 0) : 0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
...@@ -2669,6 +2689,8 @@ while (0) ...@@ -2669,6 +2689,8 @@ while (0)
case CONST_INT: \ case CONST_INT: \
if (TARGET_SHMEDIA) \ if (TARGET_SHMEDIA) \
{ \ { \
if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
return 0; \
if (CONST_OK_FOR_J (INTVAL (RTX))) \ if (CONST_OK_FOR_J (INTVAL (RTX))) \
return COSTS_N_INSNS (1); \ return COSTS_N_INSNS (1); \
else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \ else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
...@@ -3188,7 +3210,6 @@ extern int current_function_interrupt; ...@@ -3188,7 +3210,6 @@ extern int current_function_interrupt;
extern struct rtx_def *sp_switch; extern struct rtx_def *sp_switch;
extern int rtx_equal_function_value_matters; extern int rtx_equal_function_value_matters;
extern struct rtx_def *fpscr_rtx;
/* Instructions with unfilled delay slots take up an /* Instructions with unfilled delay slots take up an
...@@ -3200,23 +3221,32 @@ extern struct rtx_def *fpscr_rtx; ...@@ -3200,23 +3221,32 @@ extern struct rtx_def *fpscr_rtx;
/* Define the codes that are matched by predicates in sh.c. */ /* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \ #define PREDICATE_CODES \
{"and_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_operand", {SUBREG, REG, CONST_INT}}, \ {"arith_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_dest", {SUBREG, REG}}, \
{"arith_reg_operand", {SUBREG, REG}}, \ {"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"binary_float_operator", {PLUS, MULT}}, \ {"binary_float_operator", {PLUS, MULT}}, \
{"commutative_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}}, \ {"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fpscr_operand", {REG}}, \ {"fpscr_operand", {REG}}, \
{"fpul_operand", {REG}}, \ {"fpul_operand", {REG}}, \
{"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \ {"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \
{"general_movdst_operand", {SUBREG, REG, MEM}}, \ {"general_movdst_operand", {SUBREG, REG, MEM}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \ {"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"mextr_bit_offset", {CONST_INT}}, \
{"noncommutative_float_operator", {MINUS, DIV}}, \ {"noncommutative_float_operator", {MINUS, DIV}}, \
{"shmedia_6bit_operand", {SUBREG, REG, CONST_INT}}, \ {"shmedia_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{"target_reg_operand", {SUBREG, REG}}, \ {"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}}, \ {"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 /* 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, in a wider mode than that declared by the program. In such cases,
......
...@@ -129,6 +129,12 @@ ...@@ -129,6 +129,12 @@
(UNSPEC_CALLER 10) (UNSPEC_CALLER 10)
(UNSPEC_GOTPLT 11) (UNSPEC_GOTPLT 11)
(UNSPEC_ICACHE 12) (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. ;; These are used with unspec_volatile.
(UNSPECV_BLOCKAGE 0) (UNSPECV_BLOCKAGE 0)
...@@ -197,7 +203,7 @@ ...@@ -197,7 +203,7 @@
;; nil no-op move, will be deleted. ;; nil no-op move, will be deleted.
(define_attr "type" (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")) (const_string "other"))
;; We define a new attribute namely "insn_class".We use ;; We define a new attribute namely "insn_class".We use
...@@ -1984,14 +1990,26 @@ ...@@ -1984,14 +1990,26 @@
} }
}") }")
(define_insn "anddi3" (define_insn_and_split "anddi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r") [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
(and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r") (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
(match_operand:DI 2 "logical_operand" "r,P")))] (match_operand:DI 2 "and_operand" "r,P,n")))]
"TARGET_SHMEDIA" "TARGET_SHMEDIA"
"@ "@
and %1, %2, %0 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" (define_insn "*andcdi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r") [(set (match_operand:DI 0 "arith_reg_operand" "=r")
...@@ -3626,28 +3644,95 @@ ...@@ -3626,28 +3644,95 @@
&& GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
&& ! CONST_OK_FOR_J (INTVAL (operands[1]))" && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
[(set (match_dup 0) (match_dup 2)) [(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (match_dup 1)]
(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 = INTVAL (operands[1]);
unsigned HOST_WIDE_INT val = low; unsigned HOST_WIDE_INT low = val;
unsigned HOST_WIDE_INT high = val;
unsigned HOST_WIDE_INT sign; unsigned HOST_WIDE_INT sign;
unsigned HOST_WIDE_INT val2 = val ^ (val-1);
/* Sign-extend the 16 least-significant bits. */ /* Sign-extend the 16 least-significant bits. */
val &= 0xffff; low &= 0xffff;
val ^= 0x8000; low ^= 0x8000;
val -= 0x8000; low -= 0x8000;
operands[1] = GEN_INT (val);
/* Arithmetic shift right the word by 16 bits. */ /* Arithmetic shift right the word by 16 bits. */
low >>= 16; high >>= 16;
sign = 1; sign = 1;
sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1); sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
low ^= sign; high ^= sign;
low -= sign; high -= sign;
operands[2] = GEN_INT (low); 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 (define_split
...@@ -3690,7 +3775,7 @@ ...@@ -3690,7 +3775,7 @@
operands[2] = immed_double_const (low, high, DImode); 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") [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
(ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0") (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
(const_int 16)) (const_int 16))
...@@ -7507,7 +7592,7 @@ ...@@ -7507,7 +7592,7 @@
(define_split (define_split
[(set (reg:PSI FPSCR_REG) [(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]))" "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(set (match_dup 0) (match_dup 0))] [(set (match_dup 0) (match_dup 0))]
" "
...@@ -7521,7 +7606,7 @@ ...@@ -7521,7 +7606,7 @@
(define_split (define_split
[(set (reg:PSI FPSCR_REG) [(set (reg:PSI FPSCR_REG)
(mem:PSI (match_operand:SI 0 "register_operand" "r")))] (mem:PSI (match_operand:SI 0 "register_operand" "")))]
"TARGET_SH4" "TARGET_SH4"
[(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))] [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
" "
...@@ -8646,6 +8731,1126 @@ ...@@ -8646,6 +8731,1126 @@
"mov.l @r15+,r15\;mov.l @r15+,r0" "mov.l @r15+,r15\;mov.l @r15+,r0"
[(set_attr "length" "4")]) [(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 ;; The following description models the
;; SH4 pipeline using the DFA based scheduler. ;; SH4 pipeline using the DFA based scheduler.
;; The DFA based description is better way to model ;; The DFA based description is better way to model
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment