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
This commit is contained in:
J"orn Rennecke 2002-07-01 19:41:54 +00:00 committed by Joern Rennecke
parent 7098b619a0
commit c1b92d0906
4 changed files with 1791 additions and 30 deletions

View File

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

View File

@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */
#include "target.h"
#include "target-def.h"
#include "real.h"
#include "langhooks.h"
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
@ -204,6 +205,10 @@ static bool sh_ms_bitfield_layout_p PARAMS ((tree));
static void sh_encode_section_info PARAMS ((tree, int));
static const char *sh_strip_name_encoding PARAMS ((const char *));
static void sh_init_builtins (void);
static void sh_media_init_builtins (void);
static rtx sh_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@ -247,6 +252,11 @@ static const char *sh_strip_name_encoding PARAMS ((const char *));
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING sh_strip_name_encoding
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS sh_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN sh_expand_builtin
struct gcc_target targetm = TARGET_INITIALIZER;
/* Print the operand address in x to the stream. */
@ -320,6 +330,7 @@ print_operand_address (stream, x)
'S' print the MSW of a dp value - changes if in little endian
'T' print the next word of a dp value - same as 'R' in big endian mode.
'M' print an `x' if `m' will print `base,index'.
'N' print 'r63' if the operand is (const_int 0).
'm' print a pair `base,offset' or `base,index', for LD and ST.
'u' prints the lowest 16 bits of CONST_INT, as an unsigned value.
'o' output an operator. */
@ -422,6 +433,13 @@ print_operand (stream, x, code)
}
break;
case 'N':
if (x == const0_rtx)
{
fprintf ((stream), "r63");
break;
}
goto default_output;
case 'u':
if (GET_CODE (x) == CONST_INT)
{
@ -430,6 +448,7 @@ print_operand (stream, x, code)
}
/* Fall through. */
default_output:
default:
switch (GET_CODE (x))
{
@ -5846,6 +5865,20 @@ arith_reg_operand (op, mode)
return 0;
}
/* Like above, but for DImode destinations: forbid paradoxical DImode subregs,
because this would lead to missing sign extensions when truncating from
DImode to SImode. */
int
arith_reg_dest (op, mode)
rtx op;
enum machine_mode mode;
{
if (mode == DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
return 0;
return arith_reg_operand (op, mode);
}
int
fp_arith_reg_operand (op, mode)
rtx op;
@ -5948,6 +5981,25 @@ logical_operand (op, mode)
return 0;
}
int
and_operand (op, mode)
rtx op;
enum machine_mode mode;
{
if (logical_operand (op, mode))
return 1;
/* Check mshflo.l / mshflhi.l opportunities. */
if (TARGET_SHMEDIA
&& mode == DImode
&& GET_CODE (op) == CONST_INT
&& (INTVAL (op) == (unsigned) 0xffffffff
|| INTVAL (op) == (HOST_WIDE_INT) -1 << 32))
return 1;
return 0;
}
/* Nonzero if OP is a floating point value with value 0.0. */
int
@ -6129,6 +6181,135 @@ target_operand (op, mode)
return target_reg_operand (op, mode);
}
int
mextr_bit_offset (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
HOST_WIDE_INT i;
if (GET_CODE (op) != CONST_INT)
return 0;
i = INTVAL (op);
return i >= 1*8 && i <= 7*8 && (i & 7) == 0;
}
int
extend_reg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: arith_reg_operand) (op, mode);
}
int
extend_reg_or_0_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: arith_reg_or_0_operand) (op, mode);
}
/* Return nonzero if V is a zero vector matching MODE. */
int
zero_vec_operand (v, mode)
rtx v;
enum machine_mode mode;
{
int i;
if (GET_CODE (v) != PARALLEL
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
for (i = XVECLEN (v, 0) - 1; i >= 0; i--)
if (XVECEXP (v, 0, i) != const0_rtx)
return 0;
return 1;
}
int
sh_rep_vec (v, mode)
rtx v;
enum machine_mode mode;
{
int i;
rtx x, y;
if ((GET_CODE (v) != CONST_VECTOR && GET_CODE (v) != PARALLEL)
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
i = XVECLEN (v, 0) - 2;
x = XVECEXP (v, 0, i + 1);
if (GET_MODE_UNIT_SIZE (mode) == 1)
{
y = XVECEXP (v, 0, i);
for (i -= 2 ; i >= 0; i -= 2)
if (! rtx_equal_p (XVECEXP (v, 0, i + 1), x)
|| ! rtx_equal_p (XVECEXP (v, 0, i), y))
return 0;
}
else
for (; i >= 0; i--)
if (XVECEXP (v, 0, i) != x)
return 0;
return 1;
}
/* Determine if V is a constant vector matching MODE with only one element
that is not a sign extension. Two byte-sized elements count as one. */
int
sh_1el_vec (v, mode)
rtx v;
enum machine_mode mode;
{
int unit_size;
int i, last, least, sign_ix;
rtx sign;
if (GET_CODE (v) != CONST_VECTOR
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
/* Determine numbers of last and of least significat elements. */
last = XVECLEN (v, 0) - 1;
least = TARGET_LITTLE_ENDIAN ? 0 : last;
if (GET_CODE (XVECEXP (v, 0, least)) != CONST_INT)
return 0;
sign_ix = least;
if (GET_MODE_UNIT_SIZE (mode) == 1)
sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
if (GET_CODE (XVECEXP (v, 0, sign_ix)) != CONST_INT)
return 0;
unit_size = GET_MODE_UNIT_SIZE (GET_MODE (v));
sign = (INTVAL (XVECEXP (v, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
? constm1_rtx : const0_rtx);
i = XVECLEN (v, 0) - 1;
do
if (i != least && i != sign_ix && XVECEXP (v, 0, i) != sign)
return 0;
while (--i);
return 1;
}
int
sh_const_vec (v, mode)
rtx v;
enum machine_mode mode;
{
int i;
if (GET_CODE (v) != CONST_VECTOR
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
i = XVECLEN (v, 0) - 1;
for (; i >= 0; i--)
if (GET_CODE (XVECEXP (v, 0, i)) != CONST_INT)
return 0;
return 1;
}
/* Return the destination address of a branch. */
@ -6446,8 +6627,8 @@ sh_insn_length_adjustment (insn)
/* Instructions with unfilled delay slots take up an extra two bytes for
the nop in the delay slot. */
if (((GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
|| GET_CODE (insn) == CALL_INSN
|| (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
@ -6588,7 +6769,8 @@ legitimize_pic_address (orig, mode, reg)
/* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */
static rtx mark_constant_pool_use (x)
static rtx
mark_constant_pool_use (x)
rtx x;
{
rtx insn, lab, pattern;
@ -6848,4 +7030,299 @@ sh_strip_name_encoding (str)
return str;
}
/* 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"

View File

@ -924,8 +924,11 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
/* Value is 1 if MODE is a supported vector mode. */
#define VECTOR_MODE_SUPPORTED_P(MODE) \
(TARGET_FPU_ANY \
&& ((MODE) == V2SFmode || (MODE) == V4SFmode || (MODE) == V16SFmode))
((TARGET_FPU_ANY \
&& ((MODE) == V2SFmode || (MODE) == V4SFmode || (MODE) == V16SFmode)) \
|| (TARGET_SHMEDIA \
&& ((MODE) == V8QImode || (MODE) == V2HImode || (MODE) == V4HImode \
|| (MODE) == V2SImode)))
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
@ -2312,10 +2315,27 @@ while (0)
#define EXTRA_CONSTRAINT_T(OP) \
(NON_PIC_REFERENCE_P (OP))
/* A zero in any shape or form. */
#define EXTRA_CONSTRAINT_U(OP) \
((OP) == const0_rtx \
|| (GET_CODE (OP) == SUBREG && VECTOR_MODE_SUPPORTED_P(GET_MODE (OP)) \
&& SUBREG_REG (OP) == const0_rtx && SUBREG_BYTE (OP) == 0) \
|| GET_CODE (OP) == CONST_VECTOR && zero_vec_operand ((OP), VOIDmode))
/* Any vector constant we can handle. */
#define EXTRA_CONSTRAINT_W(OP) \
(GET_CODE (OP) == CONST_VECTOR \
&& (sh_rep_vec ((OP), VOIDmode) \
|| (HOST_BITS_PER_WIDE_INT >= 64 \
? sh_const_vec ((OP), VOIDmode) \
: sh_1el_vec ((OP), VOIDmode))))
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP) \
: (C) == 'S' ? EXTRA_CONSTRAINT_S (OP) \
: (C) == 'T' ? EXTRA_CONSTRAINT_T (OP) \
: (C) == 'U' ? EXTRA_CONSTRAINT_U (OP) \
: (C) == 'W' ? EXTRA_CONSTRAINT_W (OP) \
: 0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@ -2669,6 +2689,8 @@ while (0)
case CONST_INT: \
if (TARGET_SHMEDIA) \
{ \
if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
return 0; \
if (CONST_OK_FOR_J (INTVAL (RTX))) \
return COSTS_N_INSNS (1); \
else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
@ -3188,7 +3210,6 @@ extern int current_function_interrupt;
extern struct rtx_def *sp_switch;
extern int rtx_equal_function_value_matters;
extern struct rtx_def *fpscr_rtx;
/* Instructions with unfilled delay slots take up an
@ -3200,23 +3221,32 @@ extern struct rtx_def *fpscr_rtx;
/* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \
{"and_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_dest", {SUBREG, REG}}, \
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"binary_float_operator", {PLUS, MULT}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
{"extend_reg_or_0_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
{"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fpscr_operand", {REG}}, \
{"fpul_operand", {REG}}, \
{"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \
{"general_movdst_operand", {SUBREG, REG, MEM}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"mextr_bit_offset", {CONST_INT}}, \
{"noncommutative_float_operator", {MINUS, DIV}}, \
{"shmedia_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{"target_reg_operand", {SUBREG, REG}}, \
{"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF}}, \
{"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
{"register_operand", {SUBREG, REG}}, \
{"symbol_ref_operand", {SYMBOL_REF}},
{"sh_const_vec", {CONST_VECTOR}}, \
{"sh_1el_vec", {CONST_VECTOR, PARALLEL}}, \
{"sh_rep_vec", {CONST_VECTOR, PARALLEL}}, \
{"symbol_ref_operand", {SYMBOL_REF}}, \
{"zero_vec_operand", {CONST_VECTOR}},
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,

File diff suppressed because it is too large Load Diff