Commit 00c072ae by Claudiu Zissulescu Committed by Claudiu Zissulescu

[ARC] Add SIMD extensions for ARC HS

gcc/
2016-04-28  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.c (arc_vector_mode_supported_p): Add support for
	the new ARC HS SIMD instructions.
	(arc_preferred_simd_mode): New function.
	(arc_autovectorize_vector_sizes): Likewise.
	(TARGET_VECTORIZE_PREFERRED_SIMD_MODE)
	(TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define.
	(arc_init_reg_tables): Accept new ARC HS SIMD modes.
	(arc_init_builtins): Add new SIMD builtin types.
	(arc_split_move): Handle 64 bit vector moves.
	* config/arc/arc.h (TARGET_PLUS_DMPY, TARGET_PLUS_MACD)
	(TARGET_PLUS_QMACW): Define.
	* config/arc/builtins.def (QMACH, QMACHU, QMPYH, QMPYHU, DMACH)
	(DMACHU, DMPYH, DMPYHU, DMACWH, DMACWHU, VMAC2H, VMAC2HU, VMPY2H)
	(VMPY2HU, VADDSUB2H, VSUBADD2H, VADDSUB, VSUBADD, VADDSUB4H)
	(VSUBADD4H): New builtins.
	* config/arc/simdext.md: Add new ARC HS SIMD instructions.
	* testsuite/gcc.target/arc/builtin_simdarc.c: New file.

From-SVN: r235551
parent 174f6622
2016-04-28 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.c (arc_vector_mode_supported_p): Add support for
the new ARC HS SIMD instructions.
(arc_preferred_simd_mode): New function.
(arc_autovectorize_vector_sizes): Likewise.
(TARGET_VECTORIZE_PREFERRED_SIMD_MODE)
(TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define.
(arc_init_reg_tables): Accept new ARC HS SIMD modes.
(arc_init_builtins): Add new SIMD builtin types.
(arc_split_move): Handle 64 bit vector moves.
* config/arc/arc.h (TARGET_PLUS_DMPY, TARGET_PLUS_MACD)
(TARGET_PLUS_QMACW): Define.
* config/arc/builtins.def (QMACH, QMACHU, QMPYH, QMPYHU, DMACH)
(DMACHU, DMPYH, DMPYHU, DMACWH, DMACWHU, VMAC2H, VMAC2HU, VMPY2H)
(VMPY2HU, VADDSUB2H, VSUBADD2H, VADDSUB, VSUBADD, VADDSUB4H)
(VSUBADD4H): New builtins.
* config/arc/simdext.md: Add new ARC HS SIMD instructions.
* testsuite/gcc.target/arc/builtin_simdarc.c: New file.
2016-04-28 Eduard Sanou <dhole@openmailbox.org> 2016-04-28 Eduard Sanou <dhole@openmailbox.org>
Matthias Klose <doko@debian.org> Matthias Klose <doko@debian.org>
......
...@@ -247,16 +247,47 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT, ...@@ -247,16 +247,47 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
static bool static bool
arc_vector_mode_supported_p (machine_mode mode) arc_vector_mode_supported_p (machine_mode mode)
{ {
if (!TARGET_SIMD_SET) switch (mode)
return false; {
case V2HImode:
return TARGET_PLUS_DMPY;
case V4HImode:
case V2SImode:
return TARGET_PLUS_QMACW;
case V4SImode:
case V8HImode:
return TARGET_SIMD_SET;
if ((mode == V4SImode) default:
|| (mode == V8HImode)) return false;
return true; }
}
return false; /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
static enum machine_mode
arc_preferred_simd_mode (enum machine_mode mode)
{
switch (mode)
{
case HImode:
return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
case SImode:
return V2SImode;
default:
return word_mode;
}
} }
/* Implements target hook
TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
static unsigned int
arc_autovectorize_vector_sizes (void)
{
return TARGET_PLUS_QMACW ? (8 | 4) : 0;
}
/* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */ /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED; static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
...@@ -345,6 +376,12 @@ static void arc_finalize_pic (void); ...@@ -345,6 +376,12 @@ static void arc_finalize_pic (void);
#undef TARGET_VECTOR_MODE_SUPPORTED_P #undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
#undef TARGET_CAN_USE_DOLOOP_P #undef TARGET_CAN_USE_DOLOOP_P
#define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
...@@ -1214,7 +1251,12 @@ arc_init_reg_tables (void) ...@@ -1214,7 +1251,12 @@ arc_init_reg_tables (void)
arc_mode_class[i] = 0; arc_mode_class[i] = 0;
break; break;
case MODE_VECTOR_INT: case MODE_VECTOR_INT:
arc_mode_class [i] = (1<< (int) V_MODE); if (GET_MODE_SIZE (m) == 4)
arc_mode_class[i] = (1 << (int) S_MODE);
else if (GET_MODE_SIZE (m) == 8)
arc_mode_class[i] = (1 << (int) D_MODE);
else
arc_mode_class[i] = (1 << (int) V_MODE);
break; break;
case MODE_CC: case MODE_CC:
default: default:
...@@ -5277,6 +5319,15 @@ arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED) ...@@ -5277,6 +5319,15 @@ arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
static void static void
arc_init_builtins (void) arc_init_builtins (void)
{ {
tree V4HI_type_node;
tree V2SI_type_node;
tree V2HI_type_node;
/* Vector types based on HS SIMD elements. */
V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
tree pcvoid_type_node tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node, = build_pointer_type (build_qualified_type (void_type_node,
TYPE_QUAL_CONST)); TYPE_QUAL_CONST));
...@@ -5341,6 +5392,28 @@ arc_init_builtins (void) ...@@ -5341,6 +5392,28 @@ arc_init_builtins (void)
tree v8hi_ftype_v8hi tree v8hi_ftype_v8hi
= build_function_type_list (V8HI_type_node, V8HI_type_node, = build_function_type_list (V8HI_type_node, V8HI_type_node,
NULL_TREE); NULL_TREE);
/* ARCv2 SIMD types. */
tree long_ftype_v4hi_v4hi
= build_function_type_list (long_long_integer_type_node,
V4HI_type_node, V4HI_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 v2si_ftype_v2hi_v2hi
= build_function_type_list (V2SI_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 v2si_ftype_v2si_v2si
= build_function_type_list (V2SI_type_node,
V2SI_type_node, V2SI_type_node, NULL_TREE);
tree v4hi_ftype_v4hi_v4hi
= build_function_type_list (V4HI_type_node,
V4HI_type_node, V4HI_type_node, NULL_TREE);
tree long_ftype_v2si_v2hi
= build_function_type_list (long_long_integer_type_node,
V2SI_type_node, V2HI_type_node, NULL_TREE);
/* Add the builtins. */ /* Add the builtins. */
#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \ #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
...@@ -8706,6 +8779,31 @@ arc_split_move (rtx *operands) ...@@ -8706,6 +8779,31 @@ arc_split_move (rtx *operands)
return; return;
} }
if (TARGET_PLUS_QMACW
&& GET_CODE (operands[1]) == CONST_VECTOR)
{
HOST_WIDE_INT intval0, intval1;
if (GET_MODE (operands[1]) == V2SImode)
{
intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
}
else
{
intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
}
xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
emit_move_insn (xop[0], xop[2]);
emit_move_insn (xop[3], xop[1]);
return;
}
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0))) if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
......
...@@ -1724,6 +1724,12 @@ enum ...@@ -1724,6 +1724,12 @@ enum
/* Any multiplication feature macro. */ /* Any multiplication feature macro. */
#define TARGET_ANY_MPY \ #define TARGET_ANY_MPY \
(TARGET_MPY || TARGET_MUL64_SET || TARGET_MULMAC_32BY16_SET) (TARGET_MPY || TARGET_MUL64_SET || TARGET_MULMAC_32BY16_SET)
/* PLUS_DMPY feature macro. */
#define TARGET_PLUS_DMPY ((arc_mpy_option > 6) && TARGET_HS)
/* PLUS_MACD feature macro. */
#define TARGET_PLUS_MACD ((arc_mpy_option > 7) && TARGET_HS)
/* PLUS_QMACW feature macro. */
#define TARGET_PLUS_QMACW ((arc_mpy_option > 8) && TARGET_HS)
/* ARC600 and ARC601 feature macro. */ /* ARC600 and ARC601 feature macro. */
#define TARGET_ARC600_FAMILY (TARGET_ARC600 || TARGET_ARC601) #define TARGET_ARC600_FAMILY (TARGET_ARC600 || TARGET_ARC601)
......
...@@ -193,3 +193,30 @@ DEF_BUILTIN (VINTI, 1, void_ftype_int, vinti_insn, TARGET_SIMD_SET) ...@@ -193,3 +193,30 @@ DEF_BUILTIN (VINTI, 1, void_ftype_int, vinti_insn, TARGET_SIMD_SET)
/* END SIMD marker. */ /* END SIMD marker. */
DEF_BUILTIN (SIMD_END, 0, void_ftype_void, nothing, 0) DEF_BUILTIN (SIMD_END, 0, void_ftype_void, nothing, 0)
/* ARCv2 SIMD instructions that use/clobber the accumulator reg. */
DEF_BUILTIN (QMACH, 2, long_ftype_v4hi_v4hi, qmach, TARGET_PLUS_QMACW)
DEF_BUILTIN (QMACHU, 2, long_ftype_v4hi_v4hi, qmachu, TARGET_PLUS_QMACW)
DEF_BUILTIN (QMPYH, 2, long_ftype_v4hi_v4hi, qmpyh, TARGET_PLUS_QMACW)
DEF_BUILTIN (QMPYHU, 2, long_ftype_v4hi_v4hi, qmpyhu, TARGET_PLUS_QMACW)
DEF_BUILTIN (DMACH, 2, int_ftype_v2hi_v2hi, dmach, TARGET_PLUS_DMPY)
DEF_BUILTIN (DMACHU, 2, int_ftype_v2hi_v2hi, dmachu, TARGET_PLUS_DMPY)
DEF_BUILTIN (DMPYH, 2, int_ftype_v2hi_v2hi, dmpyh, TARGET_PLUS_DMPY)
DEF_BUILTIN (DMPYHU, 2, int_ftype_v2hi_v2hi, dmpyhu, TARGET_PLUS_DMPY)
DEF_BUILTIN (DMACWH, 2, long_ftype_v2si_v2hi, dmacwh, TARGET_PLUS_QMACW)
DEF_BUILTIN (DMACWHU, 2, long_ftype_v2si_v2hi, dmacwhu, TARGET_PLUS_QMACW)
DEF_BUILTIN (VMAC2H, 2, v2si_ftype_v2hi_v2hi, vmac2h, TARGET_PLUS_MACD)
DEF_BUILTIN (VMAC2HU, 2, v2si_ftype_v2hi_v2hi, vmac2hu, TARGET_PLUS_MACD)
DEF_BUILTIN (VMPY2H, 2, v2si_ftype_v2hi_v2hi, vmpy2h, TARGET_PLUS_MACD)
DEF_BUILTIN (VMPY2HU, 2, v2si_ftype_v2hi_v2hi, vmpy2hu, TARGET_PLUS_MACD)
/* Combined add/sub HS SIMD instructions. */
DEF_BUILTIN (VADDSUB2H, 2, v2hi_ftype_v2hi_v2hi, addsubv2hi3, TARGET_PLUS_DMPY)
DEF_BUILTIN (VSUBADD2H, 2, v2hi_ftype_v2hi_v2hi, subaddv2hi3, TARGET_PLUS_DMPY)
DEF_BUILTIN (VADDSUB, 2, v2si_ftype_v2si_v2si, addsubv2si3, TARGET_PLUS_QMACW)
DEF_BUILTIN (VSUBADD, 2, v2si_ftype_v2si_v2si, subaddv2si3, TARGET_PLUS_QMACW)
DEF_BUILTIN (VADDSUB4H, 2, v4hi_ftype_v4hi_v4hi, addsubv4hi3, TARGET_PLUS_QMACW)
DEF_BUILTIN (VSUBADD4H, 2, v4hi_ftype_v4hi_v4hi, subaddv4hi3, TARGET_PLUS_QMACW)
/* { dg-do compile } */
/* { dg-options "-mcpu=archs -O2 -Werror-implicit-function-declaration -mmpy-option=9" } */
#define STEST(name, rettype, op1type, op2type) \
rettype test_ ## name \
(op1type a, op2type b) \
{ \
return __builtin_arc_ ## name (a, b); \
}
typedef short v2hi __attribute__ ((vector_size (4)));
typedef short v4hi __attribute__ ((vector_size (8)));
typedef int v2si __attribute__ ((vector_size (8)));
STEST (qmach, long long, v4hi, v4hi)
STEST (qmachu, long long, v4hi, v4hi)
STEST (qmpyh, long long, v4hi, v4hi)
STEST (qmpyhu, long long, v4hi, v4hi)
STEST (dmach, int, v2hi, v2hi)
STEST (dmachu, int, v2hi, v2hi)
STEST (dmpyh, int, v2hi, v2hi)
STEST (dmpyhu, int, v2hi, v2hi)
STEST (dmacwh, long, v2si, v2hi)
STEST (dmacwhu, long, v2si, v2hi)
STEST (vmac2h, v2si, v2hi, v2hi)
STEST (vmac2hu, v2si, v2hi, v2hi)
STEST (vmpy2h, v2si, v2hi, v2hi)
STEST (vmpy2hu, v2si, v2hi, v2hi)
STEST (vaddsub2h, v2hi, v2hi, v2hi)
STEST (vsubadd2h, v2hi, v2hi, v2hi)
STEST (vaddsub, v2si, v2si, v2si)
STEST (vsubadd, v2si, v2si, v2si)
STEST (vaddsub4h, v4hi, v4hi, v4hi)
STEST (vsubadd4h, v4hi, v4hi, v4hi)
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