Commit 42da70b7 by Bernd Schmidt Committed by Bernd Schmidt

bfin.c: Include "optabs.h".

	* config/bfin/bfin.c: Include "optabs.h".
	(bfin_rtx_costs): Some costs for vector operations, to allow combine
	to do more work.
	(enum bfin_builtins): Add a number of fractional and vector builtins.
	(bfin_init_builtins): Likewise.
	(struct builtin_description, bdesc_2arg, bdesc_1arg): New.
	(safe_vector_operand, bfin_expand_binop_builtin,
	bfin_expand_unop_builtin): New functions.
	(bfin_expand_builtin): Handle the new builtins.
	* config/bfin/bfin.h (TARGET_CPU_CPP_BUILTINS): Define
	__ADSPBLACKFIN__.

From-SVN: r113521
parent 554006bd
...@@ -4,6 +4,18 @@ ...@@ -4,6 +4,18 @@
that this only matches CONST_INTs. All users changed to VOIDmode that this only matches CONST_INTs. All users changed to VOIDmode
operands. operands.
* config/bfin/bfin.c: Include "optabs.h".
(bfin_rtx_costs): Some costs for vector operations, to allow combine
to do more work.
(enum bfin_builtins): Add a number of fractional and vector builtins.
(bfin_init_builtins): Likewise.
(struct builtin_description, bdesc_2arg, bdesc_1arg): New.
(safe_vector_operand, bfin_expand_binop_builtin,
bfin_expand_unop_builtin): New functions.
(bfin_expand_builtin): Handle the new builtins.
* config/bfin/bfin.h (TARGET_CPU_CPP_BUILTINS): Define
__ADSPBLACKFIN__.
2006-05-04 Leehod Baruch <leehod@il.ibm.com> 2006-05-04 Leehod Baruch <leehod@il.ibm.com>
* see.c: New file. * see.c: New file.
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "expr.h" #include "expr.h"
#include "toplev.h" #include "toplev.h"
#include "recog.h" #include "recog.h"
#include "optabs.h"
#include "ggc.h" #include "ggc.h"
#include "integrate.h" #include "integrate.h"
#include "cgraph.h" #include "cgraph.h"
...@@ -2283,6 +2284,12 @@ bfin_rtx_costs (rtx x, int code, int outer_code, int *total) ...@@ -2283,6 +2284,12 @@ bfin_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (3); *total = COSTS_N_INSNS (3);
return false; return false;
case VEC_CONCAT:
case VEC_SELECT:
if (outer_code == SET)
*total = cost2;
return true;
default: default:
return false; return false;
} }
...@@ -2963,6 +2970,56 @@ enum bfin_builtins ...@@ -2963,6 +2970,56 @@ enum bfin_builtins
{ {
BFIN_BUILTIN_CSYNC, BFIN_BUILTIN_CSYNC,
BFIN_BUILTIN_SSYNC, BFIN_BUILTIN_SSYNC,
BFIN_BUILTIN_COMPOSE_2X16,
BFIN_BUILTIN_EXTRACTLO,
BFIN_BUILTIN_EXTRACTHI,
BFIN_BUILTIN_SSADD_2X16,
BFIN_BUILTIN_SSSUB_2X16,
BFIN_BUILTIN_SSADDSUB_2X16,
BFIN_BUILTIN_SSSUBADD_2X16,
BFIN_BUILTIN_MULT_2X16,
BFIN_BUILTIN_MULTR_2X16,
BFIN_BUILTIN_NEG_2X16,
BFIN_BUILTIN_ABS_2X16,
BFIN_BUILTIN_MIN_2X16,
BFIN_BUILTIN_MAX_2X16,
BFIN_BUILTIN_SSADD_1X16,
BFIN_BUILTIN_SSSUB_1X16,
BFIN_BUILTIN_MULT_1X16,
BFIN_BUILTIN_MULTR_1X16,
BFIN_BUILTIN_NORM_1X16,
BFIN_BUILTIN_NEG_1X16,
BFIN_BUILTIN_ABS_1X16,
BFIN_BUILTIN_MIN_1X16,
BFIN_BUILTIN_MAX_1X16,
BFIN_BUILTIN_DIFFHL_2X16,
BFIN_BUILTIN_DIFFLH_2X16,
BFIN_BUILTIN_SSADD_1X32,
BFIN_BUILTIN_SSSUB_1X32,
BFIN_BUILTIN_NORM_1X32,
BFIN_BUILTIN_NEG_1X32,
BFIN_BUILTIN_MIN_1X32,
BFIN_BUILTIN_MAX_1X32,
BFIN_BUILTIN_MULT_1X32,
BFIN_BUILTIN_MULHISILL,
BFIN_BUILTIN_MULHISILH,
BFIN_BUILTIN_MULHISIHL,
BFIN_BUILTIN_MULHISIHH,
BFIN_BUILTIN_LSHIFT_1X16,
BFIN_BUILTIN_LSHIFT_2X16,
BFIN_BUILTIN_SSASHIFT_1X16,
BFIN_BUILTIN_SSASHIFT_2X16,
BFIN_BUILTIN_CPLX_MUL_16,
BFIN_BUILTIN_CPLX_MAC_16,
BFIN_BUILTIN_CPLX_MSU_16,
BFIN_BUILTIN_MAX BFIN_BUILTIN_MAX
}; };
...@@ -2976,12 +3033,306 @@ do { \ ...@@ -2976,12 +3033,306 @@ do { \
static void static void
bfin_init_builtins (void) bfin_init_builtins (void)
{ {
tree V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
tree void_ftype_void tree void_ftype_void
= build_function_type (void_type_node, void_list_node); = build_function_type (void_type_node, void_list_node);
tree short_ftype_short
= build_function_type_list (short_integer_type_node, short_integer_type_node,
NULL_TREE);
tree short_ftype_int_int
= build_function_type_list (short_integer_type_node, integer_type_node,
integer_type_node, NULL_TREE);
tree int_ftype_int_int
= build_function_type_list (integer_type_node, integer_type_node,
integer_type_node, NULL_TREE);
tree int_ftype_int
= build_function_type_list (integer_type_node, integer_type_node,
NULL_TREE);
tree short_ftype_int
= build_function_type_list (short_integer_type_node, integer_type_node,
NULL_TREE);
tree int_ftype_v2hi_v2hi
= build_function_type_list (integer_type_node, V2HI_type_node,
V2HI_type_node, NULL_TREE);
tree v2hi_ftype_v2hi_v2hi
= build_function_type_list (V2HI_type_node, V2HI_type_node,
V2HI_type_node, NULL_TREE);
tree v2hi_ftype_v2hi_v2hi_v2hi
= build_function_type_list (V2HI_type_node, V2HI_type_node,
V2HI_type_node, V2HI_type_node, NULL_TREE);
tree v2hi_ftype_int_int
= build_function_type_list (V2HI_type_node, integer_type_node,
integer_type_node, NULL_TREE);
tree v2hi_ftype_v2hi_int
= build_function_type_list (V2HI_type_node, V2HI_type_node,
integer_type_node, NULL_TREE);
tree int_ftype_short_short
= build_function_type_list (integer_type_node, short_integer_type_node,
short_integer_type_node, NULL_TREE);
tree v2hi_ftype_v2hi
= build_function_type_list (V2HI_type_node, V2HI_type_node, NULL_TREE);
tree short_ftype_v2hi
= build_function_type_list (short_integer_type_node, V2HI_type_node,
NULL_TREE);
/* Add the remaining MMX insns with somewhat more complicated types. */ /* Add the remaining MMX insns with somewhat more complicated types. */
def_builtin ("__builtin_bfin_csync", void_ftype_void, BFIN_BUILTIN_CSYNC); def_builtin ("__builtin_bfin_csync", void_ftype_void, BFIN_BUILTIN_CSYNC);
def_builtin ("__builtin_bfin_ssync", void_ftype_void, BFIN_BUILTIN_SSYNC); def_builtin ("__builtin_bfin_ssync", void_ftype_void, BFIN_BUILTIN_SSYNC);
def_builtin ("__builtin_bfin_compose_2x16", v2hi_ftype_int_int,
BFIN_BUILTIN_COMPOSE_2X16);
def_builtin ("__builtin_bfin_extract_hi", short_ftype_v2hi,
BFIN_BUILTIN_EXTRACTHI);
def_builtin ("__builtin_bfin_extract_lo", short_ftype_v2hi,
BFIN_BUILTIN_EXTRACTLO);
def_builtin ("__builtin_bfin_min_fr2x16", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_MIN_2X16);
def_builtin ("__builtin_bfin_max_fr2x16", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_MAX_2X16);
def_builtin ("__builtin_bfin_add_fr2x16", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_SSADD_2X16);
def_builtin ("__builtin_bfin_sub_fr2x16", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_SSSUB_2X16);
def_builtin ("__builtin_bfin_dspaddsubsat", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_SSADDSUB_2X16);
def_builtin ("__builtin_bfin_dspsubaddsat", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_SSSUBADD_2X16);
def_builtin ("__builtin_bfin_mult_fr2x16", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_MULT_2X16);
def_builtin ("__builtin_bfin_multr_fr2x16", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_MULTR_2X16);
def_builtin ("__builtin_bfin_negate_fr2x16", v2hi_ftype_v2hi,
BFIN_BUILTIN_NEG_2X16);
def_builtin ("__builtin_bfin_abs_fr2x16", v2hi_ftype_v2hi,
BFIN_BUILTIN_ABS_2X16);
def_builtin ("__builtin_bfin_add_fr1x16", short_ftype_int_int,
BFIN_BUILTIN_SSADD_1X16);
def_builtin ("__builtin_bfin_sub_fr1x16", short_ftype_int_int,
BFIN_BUILTIN_SSSUB_1X16);
def_builtin ("__builtin_bfin_mult_fr1x16", short_ftype_int_int,
BFIN_BUILTIN_MULT_1X16);
def_builtin ("__builtin_bfin_multr_fr1x16", short_ftype_int_int,
BFIN_BUILTIN_MULTR_1X16);
def_builtin ("__builtin_bfin_negate_fr1x16", short_ftype_short,
BFIN_BUILTIN_NEG_1X16);
def_builtin ("__builtin_bfin_abs_fr1x16", short_ftype_short,
BFIN_BUILTIN_ABS_1X16);
def_builtin ("__builtin_bfin_norm_fr1x16", short_ftype_int,
BFIN_BUILTIN_NORM_1X16);
def_builtin ("__builtin_bfin_diff_hl_fr2x16", short_ftype_v2hi,
BFIN_BUILTIN_DIFFHL_2X16);
def_builtin ("__builtin_bfin_diff_lh_fr2x16", short_ftype_v2hi,
BFIN_BUILTIN_DIFFLH_2X16);
def_builtin ("__builtin_bfin_mulhisill", int_ftype_v2hi_v2hi,
BFIN_BUILTIN_MULHISILL);
def_builtin ("__builtin_bfin_mulhisihl", int_ftype_v2hi_v2hi,
BFIN_BUILTIN_MULHISIHL);
def_builtin ("__builtin_bfin_mulhisilh", int_ftype_v2hi_v2hi,
BFIN_BUILTIN_MULHISILH);
def_builtin ("__builtin_bfin_mulhisihh", int_ftype_v2hi_v2hi,
BFIN_BUILTIN_MULHISIHH);
def_builtin ("__builtin_bfin_add_fr1x32", int_ftype_int_int,
BFIN_BUILTIN_SSADD_1X32);
def_builtin ("__builtin_bfin_sub_fr1x32", int_ftype_int_int,
BFIN_BUILTIN_SSSUB_1X32);
def_builtin ("__builtin_bfin_negate_fr1x32", int_ftype_int,
BFIN_BUILTIN_NEG_1X32);
def_builtin ("__builtin_bfin_norm_fr1x32", short_ftype_int,
BFIN_BUILTIN_NORM_1X32);
def_builtin ("__builtin_bfin_mult_fr1x32", int_ftype_short_short,
BFIN_BUILTIN_MULT_1X32);
/* Shifts. */
def_builtin ("__builtin_bfin_shl_fr1x16", short_ftype_int_int,
BFIN_BUILTIN_SSASHIFT_1X16);
def_builtin ("__builtin_bfin_shl_fr2x16", v2hi_ftype_v2hi_int,
BFIN_BUILTIN_SSASHIFT_2X16);
def_builtin ("__builtin_bfin_lshl_fr1x16", short_ftype_int_int,
BFIN_BUILTIN_LSHIFT_1X16);
def_builtin ("__builtin_bfin_lshl_fr2x16", v2hi_ftype_v2hi_int,
BFIN_BUILTIN_LSHIFT_2X16);
/* Complex numbers. */
def_builtin ("__builtin_bfin_cmplx_mul", v2hi_ftype_v2hi_v2hi,
BFIN_BUILTIN_CPLX_MUL_16);
def_builtin ("__builtin_bfin_cmplx_mac", v2hi_ftype_v2hi_v2hi_v2hi,
BFIN_BUILTIN_CPLX_MAC_16);
def_builtin ("__builtin_bfin_cmplx_msu", v2hi_ftype_v2hi_v2hi_v2hi,
BFIN_BUILTIN_CPLX_MSU_16);
}
struct builtin_description
{
const enum insn_code icode;
const char *const name;
const enum bfin_builtins code;
int macflag;
};
static const struct builtin_description bdesc_2arg[] =
{
{ CODE_FOR_composev2hi, "__builtin_bfin_compose_2x16", BFIN_BUILTIN_COMPOSE_2X16, -1 },
{ CODE_FOR_ssashiftv2hi3, "__builtin_bfin_shl_fr2x16", BFIN_BUILTIN_SSASHIFT_2X16, -1 },
{ CODE_FOR_ssashifthi3, "__builtin_bfin_shl_fr1x16", BFIN_BUILTIN_SSASHIFT_1X16, -1 },
{ CODE_FOR_lshiftv2hi3, "__builtin_bfin_lshl_fr2x16", BFIN_BUILTIN_LSHIFT_2X16, -1 },
{ CODE_FOR_lshifthi3, "__builtin_bfin_lshl_fr1x16", BFIN_BUILTIN_LSHIFT_1X16, -1 },
{ CODE_FOR_sminhi3, "__builtin_bfin_min_fr1x16", BFIN_BUILTIN_MIN_1X16, -1 },
{ CODE_FOR_smaxhi3, "__builtin_bfin_max_fr1x16", BFIN_BUILTIN_MAX_1X16, -1 },
{ CODE_FOR_ssaddhi3, "__builtin_bfin_add_fr1x16", BFIN_BUILTIN_SSADD_1X16, -1 },
{ CODE_FOR_sssubhi3, "__builtin_bfin_sub_fr1x16", BFIN_BUILTIN_SSSUB_1X16, -1 },
{ CODE_FOR_sminsi3, "__builtin_bfin_min_fr1x32", BFIN_BUILTIN_MIN_1X32, -1 },
{ CODE_FOR_smaxsi3, "__builtin_bfin_max_fr1x32", BFIN_BUILTIN_MAX_1X32, -1 },
{ CODE_FOR_ssaddsi3, "__builtin_bfin_add_fr1x32", BFIN_BUILTIN_SSADD_1X32, -1 },
{ CODE_FOR_sssubsi3, "__builtin_bfin_sub_fr1x32", BFIN_BUILTIN_SSSUB_1X32, -1 },
{ CODE_FOR_sminv2hi3, "__builtin_bfin_min_fr2x16", BFIN_BUILTIN_MIN_2X16, -1 },
{ CODE_FOR_smaxv2hi3, "__builtin_bfin_max_fr2x16", BFIN_BUILTIN_MAX_2X16, -1 },
{ CODE_FOR_ssaddv2hi3, "__builtin_bfin_add_fr2x16", BFIN_BUILTIN_SSADD_2X16, -1 },
{ CODE_FOR_sssubv2hi3, "__builtin_bfin_sub_fr2x16", BFIN_BUILTIN_SSSUB_2X16, -1 },
{ CODE_FOR_ssaddsubv2hi3, "__builtin_bfin_dspaddsubsat", BFIN_BUILTIN_SSADDSUB_2X16, -1 },
{ CODE_FOR_sssubaddv2hi3, "__builtin_bfin_dspsubaddsat", BFIN_BUILTIN_SSSUBADD_2X16, -1 },
{ CODE_FOR_flag_mulhisi, "__builtin_bfin_mult_fr1x32", BFIN_BUILTIN_MULT_1X32, MACFLAG_NONE },
{ CODE_FOR_flag_mulhi, "__builtin_bfin_mult_fr1x16", BFIN_BUILTIN_MULT_1X16, MACFLAG_T },
{ CODE_FOR_flag_mulhi, "__builtin_bfin_multr_fr1x16", BFIN_BUILTIN_MULTR_1X16, MACFLAG_NONE },
{ CODE_FOR_flag_mulv2hi, "__builtin_bfin_mult_fr2x16", BFIN_BUILTIN_MULT_2X16, MACFLAG_T },
{ CODE_FOR_flag_mulv2hi, "__builtin_bfin_multr_fr2x16", BFIN_BUILTIN_MULTR_2X16, MACFLAG_NONE }
};
static const struct builtin_description bdesc_1arg[] =
{
{ CODE_FOR_signbitshi2, "__builtin_bfin_norm_fr1x16", BFIN_BUILTIN_NORM_1X16, 0 },
{ CODE_FOR_ssneghi2, "__builtin_bfin_negate_fr1x16", BFIN_BUILTIN_NEG_1X16, 0 },
{ CODE_FOR_abshi2, "__builtin_bfin_abs_fr1x16", BFIN_BUILTIN_ABS_1X16, 0 },
{ CODE_FOR_signbitssi2, "__builtin_bfin_norm_fr1x32", BFIN_BUILTIN_NORM_1X32, 0 },
{ CODE_FOR_ssnegsi2, "__builtin_bfin_negate_fr1x32", BFIN_BUILTIN_NEG_1X32, 0 },
{ CODE_FOR_movv2hi_hi_low, "__builtin_bfin_extract_lo", BFIN_BUILTIN_EXTRACTLO, 0 },
{ CODE_FOR_movv2hi_hi_high, "__builtin_bfin_extract_hi", BFIN_BUILTIN_EXTRACTHI, 0 },
{ CODE_FOR_ssnegv2hi2, "__builtin_bfin_negate_fr2x16", BFIN_BUILTIN_NEG_2X16, 0 },
{ CODE_FOR_absv2hi2, "__builtin_bfin_abs_fr2x16", BFIN_BUILTIN_ABS_2X16, 0 }
};
/* Errors in the source file can cause expand_expr to return const0_rtx
where we expect a vector. To avoid crashing, use one of the vector
clear instructions. */
static rtx
safe_vector_operand (rtx x, enum machine_mode mode)
{
if (x != const0_rtx)
return x;
x = gen_reg_rtx (SImode);
emit_insn (gen_movsi (x, CONST0_RTX (SImode)));
return gen_lowpart (mode, x);
}
/* Subroutine of bfin_expand_builtin to take care of binop insns. MACFLAG is -1
if this is a normal binary op, or one of the MACFLAG_xxx constants. */
static rtx
bfin_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target,
int macflag)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
enum machine_mode op0mode = GET_MODE (op0);
enum machine_mode op1mode = GET_MODE (op1);
enum machine_mode tmode = insn_data[icode].operand[0].mode;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
enum machine_mode mode1 = insn_data[icode].operand[2].mode;
if (VECTOR_MODE_P (mode0))
op0 = safe_vector_operand (op0, mode0);
if (VECTOR_MODE_P (mode1))
op1 = safe_vector_operand (op1, mode1);
if (! target
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
{
op0mode = HImode;
op0 = gen_lowpart (HImode, op0);
}
if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
{
op1mode = HImode;
op1 = gen_lowpart (HImode, op1);
}
/* In case the insn wants input operands in modes different from
the result, abort. */
gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
&& (op1mode == mode1 || op1mode == VOIDmode));
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
if (macflag == -1)
pat = GEN_FCN (icode) (target, op0, op1);
else
pat = GEN_FCN (icode) (target, op0, op1, GEN_INT (macflag));
if (! pat)
return 0;
emit_insn (pat);
return target;
}
/* Subroutine of bfin_expand_builtin to take care of unop insns. */
static rtx
bfin_expand_unop_builtin (enum insn_code icode, tree arglist,
rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
enum machine_mode op0mode = GET_MODE (op0);
enum machine_mode tmode = insn_data[icode].operand[0].mode;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
if (! target
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
if (VECTOR_MODE_P (mode0))
op0 = safe_vector_operand (op0, mode0);
if (op0mode == SImode && mode0 == HImode)
{
op0mode = HImode;
op0 = gen_lowpart (HImode, op0);
}
gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
pat = GEN_FCN (icode) (target, op0);
if (! pat)
return 0;
emit_insn (pat);
return target;
} }
/* Expand an expression EXP that calls a built-in function, /* Expand an expression EXP that calls a built-in function,
...@@ -2996,8 +3347,15 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, ...@@ -2996,8 +3347,15 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED) int ignore ATTRIBUTE_UNUSED)
{ {
size_t i;
enum insn_code icode;
const struct builtin_description *d;
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl); unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
tree arg0, arg1, arg2;
rtx op0, op1, op2, accvec, pat, tmp1, tmp2;
enum machine_mode tmode, mode0;
switch (fcode) switch (fcode)
{ {
...@@ -3008,9 +3366,111 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, ...@@ -3008,9 +3366,111 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
emit_insn (gen_ssync ()); emit_insn (gen_ssync ());
return 0; return 0;
case BFIN_BUILTIN_DIFFHL_2X16:
case BFIN_BUILTIN_DIFFLH_2X16:
arg0 = TREE_VALUE (arglist);
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
icode = (fcode == BFIN_BUILTIN_DIFFHL_2X16
? CODE_FOR_subhilov2hi3 : CODE_FOR_sublohiv2hi3);
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
if (! target
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
if (VECTOR_MODE_P (mode0))
op0 = safe_vector_operand (op0, mode0);
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
pat = GEN_FCN (icode) (target, op0, op0);
if (! pat)
return 0;
emit_insn (pat);
return target;
case BFIN_BUILTIN_CPLX_MUL_16:
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
accvec = gen_reg_rtx (V2PDImode);
if (! target
|| GET_MODE (target) != V2HImode
|| ! (*insn_data[icode].operand[0].predicate) (target, V2HImode))
target = gen_reg_rtx (tmode);
if (! register_operand (op0, GET_MODE (op0)))
op0 = copy_to_mode_reg (GET_MODE (op0), op0);
if (! register_operand (op1, GET_MODE (op1)))
op1 = copy_to_mode_reg (GET_MODE (op1), op1);
emit_insn (gen_flag_macinit1v2hi_parts (accvec, op0, op1, const0_rtx,
const0_rtx, const0_rtx,
const1_rtx, GEN_INT (MACFLAG_NONE)));
emit_insn (gen_flag_macv2hi_parts (target, op0, op1, const1_rtx,
const1_rtx, const1_rtx,
const0_rtx, accvec, const1_rtx, const0_rtx,
GEN_INT (MACFLAG_NONE), accvec));
return target;
case BFIN_BUILTIN_CPLX_MAC_16:
case BFIN_BUILTIN_CPLX_MSU_16:
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
accvec = gen_reg_rtx (V2PDImode);
if (! target
|| GET_MODE (target) != V2HImode
|| ! (*insn_data[icode].operand[0].predicate) (target, V2HImode))
target = gen_reg_rtx (tmode);
if (! register_operand (op0, GET_MODE (op0)))
op0 = copy_to_mode_reg (GET_MODE (op0), op0);
if (! register_operand (op1, GET_MODE (op1)))
op1 = copy_to_mode_reg (GET_MODE (op1), op1);
tmp1 = gen_reg_rtx (SImode);
tmp2 = gen_reg_rtx (SImode);
emit_insn (gen_ashlsi3 (tmp1, gen_lowpart (SImode, op2), GEN_INT (16)));
emit_move_insn (tmp2, gen_lowpart (SImode, op2));
emit_insn (gen_movstricthi_1 (gen_lowpart (HImode, tmp2), const0_rtx));
emit_insn (gen_load_accumulator_pair (accvec, tmp1, tmp2));
emit_insn (gen_flag_macv2hi_parts_acconly (accvec, op0, op1, const0_rtx,
const0_rtx, const0_rtx,
const1_rtx, accvec, const0_rtx,
const0_rtx,
GEN_INT (MACFLAG_W32)));
tmp1 = (fcode == BFIN_BUILTIN_CPLX_MAC_16 ? const1_rtx : const0_rtx);
tmp2 = (fcode == BFIN_BUILTIN_CPLX_MAC_16 ? const0_rtx : const1_rtx);
emit_insn (gen_flag_macv2hi_parts (target, op0, op1, const1_rtx,
const1_rtx, const1_rtx,
const0_rtx, accvec, tmp1, tmp2,
GEN_INT (MACFLAG_NONE), accvec));
return target;
default: default:
gcc_unreachable (); break;
} }
for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
if (d->code == fcode)
return bfin_expand_binop_builtin (d->icode, arglist, target,
d->macflag);
for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
if (d->code == fcode)
return bfin_expand_unop_builtin (d->icode, arglist, target);
gcc_unreachable ();
} }
#undef TARGET_INIT_BUILTINS #undef TARGET_INIT_BUILTINS
......
...@@ -41,6 +41,7 @@ extern int target_flags; ...@@ -41,6 +41,7 @@ extern int target_flags;
{ \ { \
builtin_define ("bfin"); \ builtin_define ("bfin"); \
builtin_define ("BFIN"); \ builtin_define ("BFIN"); \
builtin_define ("__ADSPBLACKFIN__"); \
if (TARGET_ID_SHARED_LIBRARY) \ if (TARGET_ID_SHARED_LIBRARY) \
builtin_define ("__ID_SHARED_LIB__"); \ builtin_define ("__ID_SHARED_LIB__"); \
} \ } \
......
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