Commit 229a1c59 by Jie Zhang Committed by Richard Earnshaw

Jie Zhang <jie@codesourcery.com>

	Richard Earnshaw  <rearnsha@arm.com>

	* arm.c (neon_builtin_type_bits): Remove.
	(typedef enum neon_builtin_mode): New.
	(T_MAX): Don't define.
	(typedef enum neon_builtin_datum): Remove bits, codes[],
	num_vars and base_fcode.  Add mode, code and fcode.
	(VAR1, VAR2, VAR3, VAR4, VAR5, VAR6, VAR7, VAR8, VAR9
	VAR10): Change accordingly.
	(neon_builtin_data[]): Change accordingly
	(arm_init_neon_builtins): Change accordingly.
	(neon_builtin_compare): Remove.
	(locate_neon_builtin_icode): Remove.
	(arm_expand_neon_builtin): Change accordingly.

	* arm.h (enum arm_builtins): Move to ...
	* arm.c (enum arm_builtins): ... here; and rearrange builtin code.

	* arm.c (arm_builtin_decl): Declare.
	(TARGET_BUILTIN_DECL): Define.
	(enum arm_builtins): Correct ARM_BUILTIN_MAX.
	(arm_builtin_decls[]): New.
	(arm_init_neon_builtins): Store builtin declarations in
	arm_builtin_decls[].
	(arm_init_tls_builtins): Likewise.
	(arm_init_iwmmxt_builtins): Likewise.  Refactor initialization code.
	(arm_builtin_decl): New.

Co-Authored-By: Richard Earnshaw <rearnsha@arm.com>

From-SVN: r172646
parent 75e802cc
2011-04-18 Jie Zhang <jie@codesourcery.com>
Richard Earnshaw <rearnsha@arm.com>
* arm.c (neon_builtin_type_bits): Remove.
(typedef enum neon_builtin_mode): New.
(T_MAX): Don't define.
(typedef enum neon_builtin_datum): Remove bits, codes[],
num_vars and base_fcode. Add mode, code and fcode.
(VAR1, VAR2, VAR3, VAR4, VAR5, VAR6, VAR7, VAR8, VAR9
VAR10): Change accordingly.
(neon_builtin_data[]): Change accordingly
(arm_init_neon_builtins): Change accordingly.
(neon_builtin_compare): Remove.
(locate_neon_builtin_icode): Remove.
(arm_expand_neon_builtin): Change accordingly.
* arm.h (enum arm_builtins): Move to ...
* arm.c (enum arm_builtins): ... here; and rearrange builtin code.
* arm.c (arm_builtin_decl): Declare.
(TARGET_BUILTIN_DECL): Define.
(enum arm_builtins): Correct ARM_BUILTIN_MAX.
(arm_builtin_decls[]): New.
(arm_init_neon_builtins): Store builtin declarations in
arm_builtin_decls[].
(arm_init_tls_builtins): Likewise.
(arm_init_iwmmxt_builtins): Likewise. Refactor initialization code.
(arm_builtin_decl): New.
2011-04-18 Richard Guenther <rguenther@suse.de> 2011-04-18 Richard Guenther <rguenther@suse.de>
* tree.c (upper_bound_in_type): Build properly canonicalized * tree.c (upper_bound_in_type): Build properly canonicalized
......
...@@ -161,6 +161,7 @@ static rtx safe_vector_operand (rtx, enum machine_mode); ...@@ -161,6 +161,7 @@ static rtx safe_vector_operand (rtx, enum machine_mode);
static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx); static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int); static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static tree arm_builtin_decl (unsigned, bool);
static void emit_constant_insn (rtx cond, rtx pattern); static void emit_constant_insn (rtx cond, rtx pattern);
static rtx emit_set_insn (rtx, rtx); static rtx emit_set_insn (rtx, rtx);
static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
...@@ -409,6 +410,8 @@ static const struct default_options arm_option_optimization_table[] = ...@@ -409,6 +410,8 @@ static const struct default_options arm_option_optimization_table[] =
#define TARGET_INIT_BUILTINS arm_init_builtins #define TARGET_INIT_BUILTINS arm_init_builtins
#undef TARGET_EXPAND_BUILTIN #undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN arm_expand_builtin #define TARGET_EXPAND_BUILTIN arm_expand_builtin
#undef TARGET_BUILTIN_DECL
#define TARGET_BUILTIN_DECL arm_builtin_decl
#undef TARGET_INIT_LIBFUNCS #undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS arm_init_libfuncs #define TARGET_INIT_LIBFUNCS arm_init_libfuncs
...@@ -17763,892 +17766,582 @@ arm_debugger_arg_offset (int value, rtx addr) ...@@ -17763,892 +17766,582 @@ arm_debugger_arg_offset (int value, rtx addr)
return value; return value;
} }
#define def_mbuiltin(MASK, NAME, TYPE, CODE) \ typedef enum {
do \ T_V8QI,
{ \ T_V4HI,
if ((MASK) & insn_flags) \ T_V2SI,
add_builtin_function ((NAME), (TYPE), (CODE), \ T_V2SF,
BUILT_IN_MD, NULL, NULL_TREE); \ T_DI,
} \ T_V16QI,
while (0) T_V8HI,
T_V4SI,
T_V4SF,
T_V2DI,
T_TI,
T_EI,
T_OI,
T_MAX /* Size of enum. Keep last. */
} neon_builtin_type_mode;
#define TYPE_MODE_BIT(X) (1 << (X))
#define TB_DREG (TYPE_MODE_BIT (T_V8QI) | TYPE_MODE_BIT (T_V4HI) \
| TYPE_MODE_BIT (T_V2SI) | TYPE_MODE_BIT (T_V2SF) \
| TYPE_MODE_BIT (T_DI))
#define TB_QREG (TYPE_MODE_BIT (T_V16QI) | TYPE_MODE_BIT (T_V8HI) \
| TYPE_MODE_BIT (T_V4SI) | TYPE_MODE_BIT (T_V4SF) \
| TYPE_MODE_BIT (T_V2DI) | TYPE_MODE_BIT (T_TI))
struct builtin_description #define v8qi_UP T_V8QI
{ #define v4hi_UP T_V4HI
const unsigned int mask; #define v2si_UP T_V2SI
const enum insn_code icode; #define v2sf_UP T_V2SF
const char * const name; #define di_UP T_DI
const enum arm_builtins code; #define v16qi_UP T_V16QI
const enum rtx_code comparison; #define v8hi_UP T_V8HI
const unsigned int flag; #define v4si_UP T_V4SI
}; #define v4sf_UP T_V4SF
#define v2di_UP T_V2DI
#define ti_UP T_TI
#define ei_UP T_EI
#define oi_UP T_OI
static const struct builtin_description bdesc_2arg[] = #define UP(X) X##_UP
{
#define IWMMXT_BUILTIN(code, string, builtin) \
{ FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
ARM_BUILTIN_##builtin, UNKNOWN, 0 },
IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB) typedef enum {
IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH) NEON_BINOP,
IWMMXT_BUILTIN (addv2si3, "waddw", WADDW) NEON_TERNOP,
IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB) NEON_UNOP,
IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH) NEON_GETLANE,
IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW) NEON_SETLANE,
IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB) NEON_CREATE,
IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH) NEON_DUP,
IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW) NEON_DUPLANE,
IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB) NEON_COMBINE,
IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH) NEON_SPLIT,
IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW) NEON_LANEMUL,
IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB) NEON_LANEMULL,
IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH) NEON_LANEMULH,
IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW) NEON_LANEMAC,
IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB) NEON_SCALARMUL,
IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH) NEON_SCALARMULL,
IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW) NEON_SCALARMULH,
IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL) NEON_SCALARMAC,
IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM) NEON_CONVERT,
IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM) NEON_FIXCONV,
IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB) NEON_SELECT,
IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH) NEON_RESULTPAIR,
IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW) NEON_REINTERP,
IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB) NEON_VTBL,
IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH) NEON_VTBX,
IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW) NEON_LOAD1,
IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB) NEON_LOAD1LANE,
IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH) NEON_STORE1,
IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW) NEON_STORE1LANE,
IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB) NEON_LOADSTRUCT,
IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB) NEON_LOADSTRUCTLANE,
IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH) NEON_STORESTRUCT,
IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH) NEON_STORESTRUCTLANE,
IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW) NEON_LOGICBINOP,
IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW) NEON_SHIFTINSERT,
IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB) NEON_SHIFTIMM,
IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB) NEON_SHIFTACC
IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH) } neon_itype;
IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS)
IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU)
#define IWMMXT_BUILTIN2(code, builtin) \ typedef struct {
{ FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 }, const char *name;
const neon_itype itype;
const neon_builtin_type_mode mode;
const enum insn_code code;
unsigned int fcode;
} neon_builtin_datum;
IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS) #define CF(N,X) CODE_FOR_neon_##N##X
IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
IWMMXT_BUILTIN2 (ashlv4hi3_di, WSLLH)
IWMMXT_BUILTIN2 (ashlv4hi3_iwmmxt, WSLLHI)
IWMMXT_BUILTIN2 (ashlv2si3_di, WSLLW)
IWMMXT_BUILTIN2 (ashlv2si3_iwmmxt, WSLLWI)
IWMMXT_BUILTIN2 (ashldi3_di, WSLLD)
IWMMXT_BUILTIN2 (ashldi3_iwmmxt, WSLLDI)
IWMMXT_BUILTIN2 (lshrv4hi3_di, WSRLH)
IWMMXT_BUILTIN2 (lshrv4hi3_iwmmxt, WSRLHI)
IWMMXT_BUILTIN2 (lshrv2si3_di, WSRLW)
IWMMXT_BUILTIN2 (lshrv2si3_iwmmxt, WSRLWI)
IWMMXT_BUILTIN2 (lshrdi3_di, WSRLD)
IWMMXT_BUILTIN2 (lshrdi3_iwmmxt, WSRLDI)
IWMMXT_BUILTIN2 (ashrv4hi3_di, WSRAH)
IWMMXT_BUILTIN2 (ashrv4hi3_iwmmxt, WSRAHI)
IWMMXT_BUILTIN2 (ashrv2si3_di, WSRAW)
IWMMXT_BUILTIN2 (ashrv2si3_iwmmxt, WSRAWI)
IWMMXT_BUILTIN2 (ashrdi3_di, WSRAD)
IWMMXT_BUILTIN2 (ashrdi3_iwmmxt, WSRADI)
IWMMXT_BUILTIN2 (rorv4hi3_di, WRORH)
IWMMXT_BUILTIN2 (rorv4hi3, WRORHI)
IWMMXT_BUILTIN2 (rorv2si3_di, WRORW)
IWMMXT_BUILTIN2 (rorv2si3, WRORWI)
IWMMXT_BUILTIN2 (rordi3_di, WRORD)
IWMMXT_BUILTIN2 (rordi3, WRORDI)
IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
};
static const struct builtin_description bdesc_1arg[] = #define VAR1(T, N, A) \
{#N, NEON_##T, UP (A), CF (N, A), 0}
#define VAR2(T, N, A, B) \
VAR1 (T, N, A), \
{#N, NEON_##T, UP (B), CF (N, B), 0}
#define VAR3(T, N, A, B, C) \
VAR2 (T, N, A, B), \
{#N, NEON_##T, UP (C), CF (N, C), 0}
#define VAR4(T, N, A, B, C, D) \
VAR3 (T, N, A, B, C), \
{#N, NEON_##T, UP (D), CF (N, D), 0}
#define VAR5(T, N, A, B, C, D, E) \
VAR4 (T, N, A, B, C, D), \
{#N, NEON_##T, UP (E), CF (N, E), 0}
#define VAR6(T, N, A, B, C, D, E, F) \
VAR5 (T, N, A, B, C, D, E), \
{#N, NEON_##T, UP (F), CF (N, F), 0}
#define VAR7(T, N, A, B, C, D, E, F, G) \
VAR6 (T, N, A, B, C, D, E, F), \
{#N, NEON_##T, UP (G), CF (N, G), 0}
#define VAR8(T, N, A, B, C, D, E, F, G, H) \
VAR7 (T, N, A, B, C, D, E, F, G), \
{#N, NEON_##T, UP (H), CF (N, H), 0}
#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
VAR8 (T, N, A, B, C, D, E, F, G, H), \
{#N, NEON_##T, UP (I), CF (N, I), 0}
#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
VAR9 (T, N, A, B, C, D, E, F, G, H, I), \
{#N, NEON_##T, UP (J), CF (N, J), 0}
/* The mode entries in the following table correspond to the "key" type of the
instruction variant, i.e. equivalent to that which would be specified after
the assembler mnemonic, which usually refers to the last vector operand.
(Signed/unsigned/polynomial types are not differentiated between though, and
are all mapped onto the same mode for a given element size.) The modes
listed per instruction should be the same as those defined for that
instruction's pattern in neon.md. */
static neon_builtin_datum neon_builtin_data[] =
{ {
IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB) VAR10 (BINOP, vadd,
IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH) v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW) VAR3 (BINOP, vaddl, v8qi, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB) VAR3 (BINOP, vaddw, v8qi, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH) VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW) VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB) VAR3 (BINOP, vaddhn, v8hi, v4si, v2di),
IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH) VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW) VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB) VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH) VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW) VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB) VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si),
IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH) VAR2 (TERNOP, vqdmlal, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW) VAR2 (TERNOP, vqdmlsl, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB) VAR3 (BINOP, vmull, v8qi, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH) VAR2 (SCALARMULL, vmull_n, v4hi, v2si),
IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW) VAR2 (LANEMULL, vmull_lane, v4hi, v2si),
VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si),
VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si),
VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si),
VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si),
VAR2 (BINOP, vqdmull, v4hi, v2si),
VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di),
VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di),
VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di),
VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si),
VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR10 (BINOP, vsub,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR3 (BINOP, vsubl, v8qi, v4hi, v2si),
VAR3 (BINOP, vsubw, v8qi, v4hi, v2si),
VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR3 (BINOP, vsubhn, v8hi, v4si, v2di),
VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR2 (BINOP, vcage, v2sf, v4sf),
VAR2 (BINOP, vcagt, v2sf, v4sf),
VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR3 (BINOP, vabdl, v8qi, v4hi, v2si),
VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR3 (TERNOP, vabal, v8qi, v4hi, v2si),
VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf),
VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf),
VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf),
VAR2 (BINOP, vrecps, v2sf, v4sf),
VAR2 (BINOP, vrsqrts, v2sf, v4sf),
VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
VAR2 (UNOP, vcnt, v8qi, v16qi),
VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf),
VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf),
VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
/* FIXME: vget_lane supports more variants than this! */
VAR10 (GETLANE, vget_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (SETLANE, vset_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di),
VAR10 (DUP, vdup_n,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (DUPLANE, vdup_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di),
VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di),
VAR3 (UNOP, vmovn, v8hi, v4si, v2di),
VAR3 (UNOP, vqmovn, v8hi, v4si, v2di),
VAR3 (UNOP, vqmovun, v8hi, v4si, v2di),
VAR3 (UNOP, vmovl, v8qi, v4hi, v2si),
VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR2 (LANEMAC, vmlal_lane, v4hi, v2si),
VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si),
VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si),
VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si),
VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR2 (SCALARMAC, vmlal_n, v4hi, v2si),
VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si),
VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si),
VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si),
VAR10 (BINOP, vext,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi),
VAR2 (UNOP, vrev16, v8qi, v16qi),
VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf),
VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf),
VAR10 (SELECT, vbsl,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR1 (VTBL, vtbl1, v8qi),
VAR1 (VTBL, vtbl2, v8qi),
VAR1 (VTBL, vtbl3, v8qi),
VAR1 (VTBL, vtbl4, v8qi),
VAR1 (VTBX, vtbx1, v8qi),
VAR1 (VTBX, vtbx2, v8qi),
VAR1 (VTBX, vtbx3, v8qi),
VAR1 (VTBX, vtbx4, v8qi),
VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di),
VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di),
VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di),
VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di),
VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di),
VAR5 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di),
VAR5 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (LOAD1, vld1,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (LOAD1LANE, vld1_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (LOAD1, vld1_dup,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (STORE1, vst1,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (STORE1LANE, vst1_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR9 (LOADSTRUCT,
vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
VAR7 (LOADSTRUCTLANE, vld2_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di),
VAR9 (STORESTRUCT, vst2,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
VAR7 (STORESTRUCTLANE, vst2_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR9 (LOADSTRUCT,
vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
VAR7 (LOADSTRUCTLANE, vld3_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di),
VAR9 (STORESTRUCT, vst3,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
VAR7 (STORESTRUCTLANE, vst3_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR9 (LOADSTRUCT, vld4,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
VAR7 (LOADSTRUCTLANE, vld4_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di),
VAR9 (STORESTRUCT, vst4,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
VAR7 (STORESTRUCTLANE, vst4_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
VAR10 (LOGICBINOP, vand,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (LOGICBINOP, vorr,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (BINOP, veor,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (LOGICBINOP, vbic,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
VAR10 (LOGICBINOP, vorn,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di)
};
#undef CF
#undef VAR1
#undef VAR2
#undef VAR3
#undef VAR4
#undef VAR5
#undef VAR6
#undef VAR7
#undef VAR8
#undef VAR9
#undef VAR10
/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have
symbolic names defined here (which would require too much duplication).
FIXME? */
enum arm_builtins
{
ARM_BUILTIN_GETWCX,
ARM_BUILTIN_SETWCX,
ARM_BUILTIN_WZERO,
ARM_BUILTIN_WAVG2BR,
ARM_BUILTIN_WAVG2HR,
ARM_BUILTIN_WAVG2B,
ARM_BUILTIN_WAVG2H,
ARM_BUILTIN_WACCB,
ARM_BUILTIN_WACCH,
ARM_BUILTIN_WACCW,
ARM_BUILTIN_WMACS,
ARM_BUILTIN_WMACSZ,
ARM_BUILTIN_WMACU,
ARM_BUILTIN_WMACUZ,
ARM_BUILTIN_WSADB,
ARM_BUILTIN_WSADBZ,
ARM_BUILTIN_WSADH,
ARM_BUILTIN_WSADHZ,
ARM_BUILTIN_WALIGN,
ARM_BUILTIN_TMIA,
ARM_BUILTIN_TMIAPH,
ARM_BUILTIN_TMIABB,
ARM_BUILTIN_TMIABT,
ARM_BUILTIN_TMIATB,
ARM_BUILTIN_TMIATT,
ARM_BUILTIN_TMOVMSKB,
ARM_BUILTIN_TMOVMSKH,
ARM_BUILTIN_TMOVMSKW,
ARM_BUILTIN_TBCSTB,
ARM_BUILTIN_TBCSTH,
ARM_BUILTIN_TBCSTW,
ARM_BUILTIN_WMADDS,
ARM_BUILTIN_WMADDU,
ARM_BUILTIN_WPACKHSS,
ARM_BUILTIN_WPACKWSS,
ARM_BUILTIN_WPACKDSS,
ARM_BUILTIN_WPACKHUS,
ARM_BUILTIN_WPACKWUS,
ARM_BUILTIN_WPACKDUS,
ARM_BUILTIN_WADDB,
ARM_BUILTIN_WADDH,
ARM_BUILTIN_WADDW,
ARM_BUILTIN_WADDSSB,
ARM_BUILTIN_WADDSSH,
ARM_BUILTIN_WADDSSW,
ARM_BUILTIN_WADDUSB,
ARM_BUILTIN_WADDUSH,
ARM_BUILTIN_WADDUSW,
ARM_BUILTIN_WSUBB,
ARM_BUILTIN_WSUBH,
ARM_BUILTIN_WSUBW,
ARM_BUILTIN_WSUBSSB,
ARM_BUILTIN_WSUBSSH,
ARM_BUILTIN_WSUBSSW,
ARM_BUILTIN_WSUBUSB,
ARM_BUILTIN_WSUBUSH,
ARM_BUILTIN_WSUBUSW,
ARM_BUILTIN_WAND,
ARM_BUILTIN_WANDN,
ARM_BUILTIN_WOR,
ARM_BUILTIN_WXOR,
ARM_BUILTIN_WCMPEQB,
ARM_BUILTIN_WCMPEQH,
ARM_BUILTIN_WCMPEQW,
ARM_BUILTIN_WCMPGTUB,
ARM_BUILTIN_WCMPGTUH,
ARM_BUILTIN_WCMPGTUW,
ARM_BUILTIN_WCMPGTSB,
ARM_BUILTIN_WCMPGTSH,
ARM_BUILTIN_WCMPGTSW,
ARM_BUILTIN_TEXTRMSB,
ARM_BUILTIN_TEXTRMSH,
ARM_BUILTIN_TEXTRMSW,
ARM_BUILTIN_TEXTRMUB,
ARM_BUILTIN_TEXTRMUH,
ARM_BUILTIN_TEXTRMUW,
ARM_BUILTIN_TINSRB,
ARM_BUILTIN_TINSRH,
ARM_BUILTIN_TINSRW,
ARM_BUILTIN_WMAXSW,
ARM_BUILTIN_WMAXSH,
ARM_BUILTIN_WMAXSB,
ARM_BUILTIN_WMAXUW,
ARM_BUILTIN_WMAXUH,
ARM_BUILTIN_WMAXUB,
ARM_BUILTIN_WMINSW,
ARM_BUILTIN_WMINSH,
ARM_BUILTIN_WMINSB,
ARM_BUILTIN_WMINUW,
ARM_BUILTIN_WMINUH,
ARM_BUILTIN_WMINUB,
ARM_BUILTIN_WMULUM,
ARM_BUILTIN_WMULSM,
ARM_BUILTIN_WMULUL,
ARM_BUILTIN_PSADBH,
ARM_BUILTIN_WSHUFH,
ARM_BUILTIN_WSLLH,
ARM_BUILTIN_WSLLW,
ARM_BUILTIN_WSLLD,
ARM_BUILTIN_WSRAH,
ARM_BUILTIN_WSRAW,
ARM_BUILTIN_WSRAD,
ARM_BUILTIN_WSRLH,
ARM_BUILTIN_WSRLW,
ARM_BUILTIN_WSRLD,
ARM_BUILTIN_WRORH,
ARM_BUILTIN_WRORW,
ARM_BUILTIN_WRORD,
ARM_BUILTIN_WSLLHI,
ARM_BUILTIN_WSLLWI,
ARM_BUILTIN_WSLLDI,
ARM_BUILTIN_WSRAHI,
ARM_BUILTIN_WSRAWI,
ARM_BUILTIN_WSRADI,
ARM_BUILTIN_WSRLHI,
ARM_BUILTIN_WSRLWI,
ARM_BUILTIN_WSRLDI,
ARM_BUILTIN_WRORHI,
ARM_BUILTIN_WRORWI,
ARM_BUILTIN_WRORDI,
ARM_BUILTIN_WUNPCKIHB,
ARM_BUILTIN_WUNPCKIHH,
ARM_BUILTIN_WUNPCKIHW,
ARM_BUILTIN_WUNPCKILB,
ARM_BUILTIN_WUNPCKILH,
ARM_BUILTIN_WUNPCKILW,
ARM_BUILTIN_WUNPCKEHSB,
ARM_BUILTIN_WUNPCKEHSH,
ARM_BUILTIN_WUNPCKEHSW,
ARM_BUILTIN_WUNPCKEHUB,
ARM_BUILTIN_WUNPCKEHUH,
ARM_BUILTIN_WUNPCKEHUW,
ARM_BUILTIN_WUNPCKELSB,
ARM_BUILTIN_WUNPCKELSH,
ARM_BUILTIN_WUNPCKELSW,
ARM_BUILTIN_WUNPCKELUB,
ARM_BUILTIN_WUNPCKELUH,
ARM_BUILTIN_WUNPCKELUW,
ARM_BUILTIN_THREAD_POINTER,
ARM_BUILTIN_NEON_BASE,
ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data)
}; };
/* Set up all the iWMMXt builtins. This is static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX];
not called if TARGET_IWMMXT is zero. */
static void static void
arm_init_iwmmxt_builtins (void) arm_init_neon_builtins (void)
{ {
const struct builtin_description * d; unsigned int i, fcode;
size_t i; tree decl;
tree endlink = void_list_node;
tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode); tree neon_intQI_type_node;
tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode); tree neon_intHI_type_node;
tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode); tree neon_polyQI_type_node;
tree neon_polyHI_type_node;
tree neon_intSI_type_node;
tree neon_intDI_type_node;
tree neon_float_type_node;
tree int_ftype_int tree intQI_pointer_node;
= build_function_type (integer_type_node, tree intHI_pointer_node;
tree_cons (NULL_TREE, integer_type_node, endlink)); tree intSI_pointer_node;
tree v8qi_ftype_v8qi_v8qi_int tree intDI_pointer_node;
= build_function_type (V8QI_type_node, tree float_pointer_node;
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree v4hi_ftype_v4hi_int
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_v2si_int
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_di_di
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
endlink)));
tree di_ftype_di_int
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree di_ftype_di_int_int
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree int_ftype_v8qi
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink));
tree int_ftype_v4hi
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink));
tree int_ftype_v2si
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink));
tree int_ftype_v8qi_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree int_ftype_v4hi_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree int_ftype_v2si_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v8qi_ftype_v8qi_int_int
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree v4hi_ftype_v4hi_int_int
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree v2si_ftype_v2si_int_int
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
/* Miscellaneous. */
tree v8qi_ftype_v4hi_v4hi
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
tree v4hi_ftype_v2si_v2si
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink)));
tree v2si_ftype_v4hi_v4hi
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
tree v2si_ftype_v8qi_v8qi
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink)));
tree v4hi_ftype_v4hi_di
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE,
long_long_integer_type_node,
endlink)));
tree v2si_ftype_v2si_di
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE,
long_long_integer_type_node,
endlink)));
tree void_ftype_int_int
= build_function_type (void_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree di_ftype_void
= build_function_type (long_long_unsigned_type_node, endlink);
tree di_ftype_v8qi
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink));
tree di_ftype_v4hi
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink));
tree di_ftype_v2si
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink));
tree v2si_ftype_v4hi
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink));
tree v4hi_ftype_v8qi
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink));
tree di_ftype_di_v4hi_v4hi
= build_function_type (long_long_unsigned_type_node,
tree_cons (NULL_TREE,
long_long_unsigned_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE,
V4HI_type_node,
endlink))));
tree di_ftype_v4hi_v4hi
= build_function_type (long_long_unsigned_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
/* Normal vector binops. */
tree v8qi_ftype_v8qi_v8qi
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink)));
tree v4hi_ftype_v4hi_v4hi
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
tree v2si_ftype_v2si_v2si
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink)));
tree di_ftype_di_di
= build_function_type (long_long_unsigned_type_node,
tree_cons (NULL_TREE, long_long_unsigned_type_node,
tree_cons (NULL_TREE,
long_long_unsigned_type_node,
endlink)));
/* Add all builtins that are more or less simple operations on two tree const_intQI_node;
operands. */ tree const_intHI_node;
for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) tree const_intSI_node;
{ tree const_intDI_node;
/* Use one of the operands; the target can have a different mode for tree const_float_node;
mask-generating compares. */
enum machine_mode mode;
tree type;
if (d->name == 0) tree const_intQI_pointer_node;
continue; tree const_intHI_pointer_node;
tree const_intSI_pointer_node;
tree const_intDI_pointer_node;
tree const_float_pointer_node;
mode = insn_data[d->icode].operand[1].mode; tree V8QI_type_node;
tree V4HI_type_node;
tree V2SI_type_node;
tree V2SF_type_node;
tree V16QI_type_node;
tree V8HI_type_node;
tree V4SI_type_node;
tree V4SF_type_node;
tree V2DI_type_node;
switch (mode) tree intUQI_type_node;
{ tree intUHI_type_node;
case V8QImode: tree intUSI_type_node;
type = v8qi_ftype_v8qi_v8qi; tree intUDI_type_node;
break;
case V4HImode:
type = v4hi_ftype_v4hi_v4hi;
break;
case V2SImode:
type = v2si_ftype_v2si_v2si;
break;
case DImode:
type = di_ftype_di_di;
break;
default: tree intEI_type_node;
gcc_unreachable (); tree intOI_type_node;
} tree intCI_type_node;
tree intXI_type_node;
def_mbuiltin (d->mask, d->name, type, d->code); tree V8QI_pointer_node;
} tree V4HI_pointer_node;
tree V2SI_pointer_node;
tree V2SF_pointer_node;
tree V16QI_pointer_node;
tree V8HI_pointer_node;
tree V4SI_pointer_node;
tree V4SF_pointer_node;
tree V2DI_pointer_node;
/* Add the remaining MMX insns with somewhat more complicated types. */ tree void_ftype_pv8qi_v8qi_v8qi;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wzero", di_ftype_void, ARM_BUILTIN_WZERO); tree void_ftype_pv4hi_v4hi_v4hi;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_setwcx", void_ftype_int_int, ARM_BUILTIN_SETWCX); tree void_ftype_pv2si_v2si_v2si;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_getwcx", int_ftype_int, ARM_BUILTIN_GETWCX); tree void_ftype_pv2sf_v2sf_v2sf;
tree void_ftype_pdi_di_di;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSLLH); tree void_ftype_pv16qi_v16qi_v16qi;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllw", v2si_ftype_v2si_di, ARM_BUILTIN_WSLLW); tree void_ftype_pv8hi_v8hi_v8hi;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslld", di_ftype_di_di, ARM_BUILTIN_WSLLD); tree void_ftype_pv4si_v4si_v4si;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSLLHI); tree void_ftype_pv4sf_v4sf_v4sf;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSLLWI); tree void_ftype_pv2di_v2di_v2di;
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslldi", di_ftype_di_int, ARM_BUILTIN_WSLLDI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRLH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRLW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrld", di_ftype_di_di, ARM_BUILTIN_WSRLD);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRLHI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRLWI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrldi", di_ftype_di_int, ARM_BUILTIN_WSRLDI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrah", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRAH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsraw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRAW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrad", di_ftype_di_di, ARM_BUILTIN_WSRAD);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrahi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRAHI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrawi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRAWI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsradi", di_ftype_di_int, ARM_BUILTIN_WSRADI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WRORH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorw", v2si_ftype_v2si_di, ARM_BUILTIN_WRORW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrord", di_ftype_di_di, ARM_BUILTIN_WRORD);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WRORHI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorwi", v2si_ftype_v2si_int, ARM_BUILTIN_WRORWI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrordi", di_ftype_di_int, ARM_BUILTIN_WRORDI);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wshufh", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSHUFH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadb", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadh", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadbz", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADBZ);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadhz", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADHZ);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsb", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMSB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMSH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMSW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmub", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMUB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMUH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMUW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrb", v8qi_ftype_v8qi_int_int, ARM_BUILTIN_TINSRB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrh", v4hi_ftype_v4hi_int_int, ARM_BUILTIN_TINSRH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrw", v2si_ftype_v2si_int_int, ARM_BUILTIN_TINSRW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccb", di_ftype_v8qi, ARM_BUILTIN_WACCB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wacch", di_ftype_v4hi, ARM_BUILTIN_WACCH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccw", di_ftype_v2si, ARM_BUILTIN_WACCW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskb", int_ftype_v8qi, ARM_BUILTIN_TMOVMSKB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskh", int_ftype_v4hi, ARM_BUILTIN_TMOVMSKH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskw", int_ftype_v2si, ARM_BUILTIN_TMOVMSKW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhss", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHSS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhus", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHUS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwus", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWUS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwss", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWSS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdus", v2si_ftype_di_di, ARM_BUILTIN_WPACKDUS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdss", v2si_ftype_di_di, ARM_BUILTIN_WPACKDSS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHUB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHUH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHUW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHSB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHSH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHSW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELUB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELUH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELUW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELSB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELSH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELSW);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacs", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACS);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacsz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACSZ);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacu", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACU);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacuz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACUZ);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_walign", v8qi_ftype_v8qi_v8qi_int, ARM_BUILTIN_WALIGN);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmia", di_ftype_di_int_int, ARM_BUILTIN_TMIA);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiaph", di_ftype_di_int_int, ARM_BUILTIN_TMIAPH);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabb", di_ftype_di_int_int, ARM_BUILTIN_TMIABB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabt", di_ftype_di_int_int, ARM_BUILTIN_TMIABT);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatb", di_ftype_di_int_int, ARM_BUILTIN_TMIATB);
def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatt", di_ftype_di_int_int, ARM_BUILTIN_TMIATT);
}
static void tree reinterp_ftype_dreg[5][5];
arm_init_tls_builtins (void) tree reinterp_ftype_qreg[5][5];
{ tree dreg_types[5], qreg_types[5];
tree ftype, decl;
ftype = build_function_type (ptr_type_node, void_list_node);
decl = add_builtin_function ("__builtin_thread_pointer", ftype,
ARM_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
NULL, NULL_TREE);
TREE_NOTHROW (decl) = 1;
TREE_READONLY (decl) = 1;
}
enum neon_builtin_type_bits {
T_V8QI = 0x0001,
T_V4HI = 0x0002,
T_V2SI = 0x0004,
T_V2SF = 0x0008,
T_DI = 0x0010,
T_DREG = 0x001F,
T_V16QI = 0x0020,
T_V8HI = 0x0040,
T_V4SI = 0x0080,
T_V4SF = 0x0100,
T_V2DI = 0x0200,
T_TI = 0x0400,
T_QREG = 0x07E0,
T_EI = 0x0800,
T_OI = 0x1000
};
#define v8qi_UP T_V8QI
#define v4hi_UP T_V4HI
#define v2si_UP T_V2SI
#define v2sf_UP T_V2SF
#define di_UP T_DI
#define v16qi_UP T_V16QI
#define v8hi_UP T_V8HI
#define v4si_UP T_V4SI
#define v4sf_UP T_V4SF
#define v2di_UP T_V2DI
#define ti_UP T_TI
#define ei_UP T_EI
#define oi_UP T_OI
#define UP(X) X##_UP
#define T_MAX 13
typedef enum {
NEON_BINOP,
NEON_TERNOP,
NEON_UNOP,
NEON_GETLANE,
NEON_SETLANE,
NEON_CREATE,
NEON_DUP,
NEON_DUPLANE,
NEON_COMBINE,
NEON_SPLIT,
NEON_LANEMUL,
NEON_LANEMULL,
NEON_LANEMULH,
NEON_LANEMAC,
NEON_SCALARMUL,
NEON_SCALARMULL,
NEON_SCALARMULH,
NEON_SCALARMAC,
NEON_CONVERT,
NEON_FIXCONV,
NEON_SELECT,
NEON_RESULTPAIR,
NEON_REINTERP,
NEON_VTBL,
NEON_VTBX,
NEON_LOAD1,
NEON_LOAD1LANE,
NEON_STORE1,
NEON_STORE1LANE,
NEON_LOADSTRUCT,
NEON_LOADSTRUCTLANE,
NEON_STORESTRUCT,
NEON_STORESTRUCTLANE,
NEON_LOGICBINOP,
NEON_SHIFTINSERT,
NEON_SHIFTIMM,
NEON_SHIFTACC
} neon_itype;
typedef struct {
const char *name;
const neon_itype itype;
const int bits;
const enum insn_code codes[T_MAX];
const unsigned int num_vars;
unsigned int base_fcode;
} neon_builtin_datum;
#define CF(N,X) CODE_FOR_neon_##N##X
#define VAR1(T, N, A) \
#N, NEON_##T, UP (A), { CF (N, A) }, 1, 0
#define VAR2(T, N, A, B) \
#N, NEON_##T, UP (A) | UP (B), { CF (N, A), CF (N, B) }, 2, 0
#define VAR3(T, N, A, B, C) \
#N, NEON_##T, UP (A) | UP (B) | UP (C), \
{ CF (N, A), CF (N, B), CF (N, C) }, 3, 0
#define VAR4(T, N, A, B, C, D) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D) }, 4, 0
#define VAR5(T, N, A, B, C, D, E) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E) }, 5, 0
#define VAR6(T, N, A, B, C, D, E, F) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E) | UP (F), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F) }, 6, 0
#define VAR7(T, N, A, B, C, D, E, F, G) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E) | UP (F) | UP (G), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
CF (N, G) }, 7, 0
#define VAR8(T, N, A, B, C, D, E, F, G, H) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E) | UP (F) | UP (G) \
| UP (H), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
CF (N, G), CF (N, H) }, 8, 0
#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E) | UP (F) | UP (G) \
| UP (H) | UP (I), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
CF (N, G), CF (N, H), CF (N, I) }, 9, 0
#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
#N, NEON_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E) | UP (F) | UP (G) \
| UP (H) | UP (I) | UP (J), \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
CF (N, G), CF (N, H), CF (N, I), CF (N, J) }, 10, 0
/* The mode entries in the following table correspond to the "key" type of the
instruction variant, i.e. equivalent to that which would be specified after
the assembler mnemonic, which usually refers to the last vector operand.
(Signed/unsigned/polynomial types are not differentiated between though, and
are all mapped onto the same mode for a given element size.) The modes
listed per instruction should be the same as those defined for that
instruction's pattern in neon.md.
WARNING: Variants should be listed in the same increasing order as
neon_builtin_type_bits. */
static neon_builtin_datum neon_builtin_data[] =
{
{ VAR10 (BINOP, vadd,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR3 (BINOP, vaddl, v8qi, v4hi, v2si) },
{ VAR3 (BINOP, vaddw, v8qi, v4hi, v2si) },
{ VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR3 (BINOP, vaddhn, v8hi, v4si, v2di) },
{ VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si) },
{ VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si) },
{ VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si) },
{ VAR2 (TERNOP, vqdmlal, v4hi, v2si) },
{ VAR2 (TERNOP, vqdmlsl, v4hi, v2si) },
{ VAR3 (BINOP, vmull, v8qi, v4hi, v2si) },
{ VAR2 (SCALARMULL, vmull_n, v4hi, v2si) },
{ VAR2 (LANEMULL, vmull_lane, v4hi, v2si) },
{ VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si) },
{ VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si) },
{ VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si) },
{ VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si) },
{ VAR2 (BINOP, vqdmull, v4hi, v2si) },
{ VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di) },
{ VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di) },
{ VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di) },
{ VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si) },
{ VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR10 (BINOP, vsub,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR3 (BINOP, vsubl, v8qi, v4hi, v2si) },
{ VAR3 (BINOP, vsubw, v8qi, v4hi, v2si) },
{ VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR3 (BINOP, vsubhn, v8hi, v4si, v2di) },
{ VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR2 (BINOP, vcage, v2sf, v4sf) },
{ VAR2 (BINOP, vcagt, v2sf, v4sf) },
{ VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR3 (BINOP, vabdl, v8qi, v4hi, v2si) },
{ VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR3 (TERNOP, vabal, v8qi, v4hi, v2si) },
{ VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf) },
{ VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf) },
{ VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf) },
{ VAR2 (BINOP, vrecps, v2sf, v4sf) },
{ VAR2 (BINOP, vrsqrts, v2sf, v4sf) },
{ VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
{ VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
{ VAR2 (UNOP, vcnt, v8qi, v16qi) },
{ VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf) },
{ VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf) },
{ VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
/* FIXME: vget_lane supports more variants than this! */
{ VAR10 (GETLANE, vget_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (SETLANE, vset_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di) },
{ VAR10 (DUP, vdup_n,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (DUPLANE, vdup_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di) },
{ VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR3 (UNOP, vmovn, v8hi, v4si, v2di) },
{ VAR3 (UNOP, vqmovn, v8hi, v4si, v2di) },
{ VAR3 (UNOP, vqmovun, v8hi, v4si, v2di) },
{ VAR3 (UNOP, vmovl, v8qi, v4hi, v2si) },
{ VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR2 (LANEMAC, vmlal_lane, v4hi, v2si) },
{ VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si) },
{ VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si) },
{ VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si) },
{ VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR2 (SCALARMAC, vmlal_n, v4hi, v2si) },
{ VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si) },
{ VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si) },
{ VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si) },
{ VAR10 (BINOP, vext,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi) },
{ VAR2 (UNOP, vrev16, v8qi, v16qi) },
{ VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf) },
{ VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf) },
{ VAR10 (SELECT, vbsl,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR1 (VTBL, vtbl1, v8qi) },
{ VAR1 (VTBL, vtbl2, v8qi) },
{ VAR1 (VTBL, vtbl3, v8qi) },
{ VAR1 (VTBL, vtbl4, v8qi) },
{ VAR1 (VTBX, vtbx1, v8qi) },
{ VAR1 (VTBX, vtbx2, v8qi) },
{ VAR1 (VTBX, vtbx3, v8qi) },
{ VAR1 (VTBX, vtbx4, v8qi) },
{ VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf) },
{ VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di) },
{ VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di) },
{ VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di) },
{ VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di) },
{ VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di) },
{ VAR5 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR5 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (LOAD1, vld1,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (LOAD1LANE, vld1_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (LOAD1, vld1_dup,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (STORE1, vst1,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (STORE1LANE, vst1_lane,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR9 (LOADSTRUCT,
vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf) },
{ VAR7 (LOADSTRUCTLANE, vld2_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di) },
{ VAR9 (STORESTRUCT, vst2,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf) },
{ VAR7 (STORESTRUCTLANE, vst2_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR9 (LOADSTRUCT,
vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf) },
{ VAR7 (LOADSTRUCTLANE, vld3_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di) },
{ VAR9 (STORESTRUCT, vst3,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf) },
{ VAR7 (STORESTRUCTLANE, vst3_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR9 (LOADSTRUCT, vld4,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf) },
{ VAR7 (LOADSTRUCTLANE, vld4_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di) },
{ VAR9 (STORESTRUCT, vst4,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf) },
{ VAR7 (STORESTRUCTLANE, vst4_lane,
v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf) },
{ VAR10 (LOGICBINOP, vand,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (LOGICBINOP, vorr,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (BINOP, veor,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (LOGICBINOP, vbic,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) },
{ VAR10 (LOGICBINOP, vorn,
v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di) }
};
#undef CF
#undef VAR1
#undef VAR2
#undef VAR3
#undef VAR4
#undef VAR5
#undef VAR6
#undef VAR7
#undef VAR8
#undef VAR9
#undef VAR10
static void
arm_init_neon_builtins (void)
{
unsigned int i, fcode = ARM_BUILTIN_NEON_BASE;
tree neon_intQI_type_node;
tree neon_intHI_type_node;
tree neon_polyQI_type_node;
tree neon_polyHI_type_node;
tree neon_intSI_type_node;
tree neon_intDI_type_node;
tree neon_float_type_node;
tree intQI_pointer_node;
tree intHI_pointer_node;
tree intSI_pointer_node;
tree intDI_pointer_node;
tree float_pointer_node;
tree const_intQI_node;
tree const_intHI_node;
tree const_intSI_node;
tree const_intDI_node;
tree const_float_node;
tree const_intQI_pointer_node;
tree const_intHI_pointer_node;
tree const_intSI_pointer_node;
tree const_intDI_pointer_node;
tree const_float_pointer_node;
tree V8QI_type_node;
tree V4HI_type_node;
tree V2SI_type_node;
tree V2SF_type_node;
tree V16QI_type_node;
tree V8HI_type_node;
tree V4SI_type_node;
tree V4SF_type_node;
tree V2DI_type_node;
tree intUQI_type_node;
tree intUHI_type_node;
tree intUSI_type_node;
tree intUDI_type_node;
tree intEI_type_node;
tree intOI_type_node;
tree intCI_type_node;
tree intXI_type_node;
tree V8QI_pointer_node;
tree V4HI_pointer_node;
tree V2SI_pointer_node;
tree V2SF_pointer_node;
tree V16QI_pointer_node;
tree V8HI_pointer_node;
tree V4SI_pointer_node;
tree V4SF_pointer_node;
tree V2DI_pointer_node;
tree void_ftype_pv8qi_v8qi_v8qi;
tree void_ftype_pv4hi_v4hi_v4hi;
tree void_ftype_pv2si_v2si_v2si;
tree void_ftype_pv2sf_v2sf_v2sf;
tree void_ftype_pdi_di_di;
tree void_ftype_pv16qi_v16qi_v16qi;
tree void_ftype_pv8hi_v8hi_v8hi;
tree void_ftype_pv4si_v4si_v4si;
tree void_ftype_pv4sf_v4sf_v4sf;
tree void_ftype_pv2di_v2di_v2di;
tree reinterp_ftype_dreg[5][5];
tree reinterp_ftype_qreg[5][5];
tree dreg_types[5], qreg_types[5];
/* Create distinguished type nodes for NEON vector element types, /* Create distinguished type nodes for NEON vector element types,
and pointers to values of such types, so we can detect them later. */ and pointers to values of such types, so we can detect them later. */
...@@ -18807,268 +18500,758 @@ arm_init_neon_builtins (void) ...@@ -18807,268 +18500,758 @@ arm_init_neon_builtins (void)
dreg_types[3] = V2SF_type_node; dreg_types[3] = V2SF_type_node;
dreg_types[4] = neon_intDI_type_node; dreg_types[4] = neon_intDI_type_node;
qreg_types[0] = V16QI_type_node; qreg_types[0] = V16QI_type_node;
qreg_types[1] = V8HI_type_node; qreg_types[1] = V8HI_type_node;
qreg_types[2] = V4SI_type_node; qreg_types[2] = V4SI_type_node;
qreg_types[3] = V4SF_type_node; qreg_types[3] = V4SF_type_node;
qreg_types[4] = V2DI_type_node; qreg_types[4] = V2DI_type_node;
for (i = 0; i < 5; i++)
{
int j;
for (j = 0; j < 5; j++)
{
reinterp_ftype_dreg[i][j]
= build_function_type_list (dreg_types[i], dreg_types[j], NULL);
reinterp_ftype_qreg[i][j]
= build_function_type_list (qreg_types[i], qreg_types[j], NULL);
}
}
for (i = 0, fcode = ARM_BUILTIN_NEON_BASE;
i < ARRAY_SIZE (neon_builtin_data);
i++, fcode++)
{
neon_builtin_datum *d = &neon_builtin_data[i];
const char* const modenames[] = {
"v8qi", "v4hi", "v2si", "v2sf", "di",
"v16qi", "v8hi", "v4si", "v4sf", "v2di",
"ti", "ei", "oi"
};
char namebuf[60];
tree ftype = NULL;
int is_load = 0, is_store = 0;
gcc_assert (ARRAY_SIZE (modenames) == T_MAX);
d->fcode = fcode;
switch (d->itype)
{
case NEON_LOAD1:
case NEON_LOAD1LANE:
case NEON_LOADSTRUCT:
case NEON_LOADSTRUCTLANE:
is_load = 1;
/* Fall through. */
case NEON_STORE1:
case NEON_STORE1LANE:
case NEON_STORESTRUCT:
case NEON_STORESTRUCTLANE:
if (!is_load)
is_store = 1;
/* Fall through. */
case NEON_UNOP:
case NEON_BINOP:
case NEON_LOGICBINOP:
case NEON_SHIFTINSERT:
case NEON_TERNOP:
case NEON_GETLANE:
case NEON_SETLANE:
case NEON_CREATE:
case NEON_DUP:
case NEON_DUPLANE:
case NEON_SHIFTIMM:
case NEON_SHIFTACC:
case NEON_COMBINE:
case NEON_SPLIT:
case NEON_CONVERT:
case NEON_FIXCONV:
case NEON_LANEMUL:
case NEON_LANEMULL:
case NEON_LANEMULH:
case NEON_LANEMAC:
case NEON_SCALARMUL:
case NEON_SCALARMULL:
case NEON_SCALARMULH:
case NEON_SCALARMAC:
case NEON_SELECT:
case NEON_VTBL:
case NEON_VTBX:
{
int k;
tree return_type = void_type_node, args = void_list_node;
/* Build a function type directly from the insn_data for
this builtin. The build_function_type() function takes
care of removing duplicates for us. */
for (k = insn_data[d->code].n_generator_args - 1; k >= 0; k--)
{
tree eltype;
if (is_load && k == 1)
{
/* Neon load patterns always have the memory
operand in the operand 1 position. */
gcc_assert (insn_data[d->code].operand[k].predicate
== neon_struct_operand);
switch (d->mode)
{
case T_V8QI:
case T_V16QI:
eltype = const_intQI_pointer_node;
break;
case T_V4HI:
case T_V8HI:
eltype = const_intHI_pointer_node;
break;
case T_V2SI:
case T_V4SI:
eltype = const_intSI_pointer_node;
break;
case T_V2SF:
case T_V4SF:
eltype = const_float_pointer_node;
break;
case T_DI:
case T_V2DI:
eltype = const_intDI_pointer_node;
break;
default: gcc_unreachable ();
}
}
else if (is_store && k == 0)
{
/* Similarly, Neon store patterns use operand 0 as
the memory location to store to. */
gcc_assert (insn_data[d->code].operand[k].predicate
== neon_struct_operand);
switch (d->mode)
{
case T_V8QI:
case T_V16QI:
eltype = intQI_pointer_node;
break;
case T_V4HI:
case T_V8HI:
eltype = intHI_pointer_node;
break;
case T_V2SI:
case T_V4SI:
eltype = intSI_pointer_node;
break;
case T_V2SF:
case T_V4SF:
eltype = float_pointer_node;
break;
case T_DI:
case T_V2DI:
eltype = intDI_pointer_node;
break;
default: gcc_unreachable ();
}
}
else
{
switch (insn_data[d->code].operand[k].mode)
{
case VOIDmode: eltype = void_type_node; break;
/* Scalars. */
case QImode: eltype = neon_intQI_type_node; break;
case HImode: eltype = neon_intHI_type_node; break;
case SImode: eltype = neon_intSI_type_node; break;
case SFmode: eltype = neon_float_type_node; break;
case DImode: eltype = neon_intDI_type_node; break;
case TImode: eltype = intTI_type_node; break;
case EImode: eltype = intEI_type_node; break;
case OImode: eltype = intOI_type_node; break;
case CImode: eltype = intCI_type_node; break;
case XImode: eltype = intXI_type_node; break;
/* 64-bit vectors. */
case V8QImode: eltype = V8QI_type_node; break;
case V4HImode: eltype = V4HI_type_node; break;
case V2SImode: eltype = V2SI_type_node; break;
case V2SFmode: eltype = V2SF_type_node; break;
/* 128-bit vectors. */
case V16QImode: eltype = V16QI_type_node; break;
case V8HImode: eltype = V8HI_type_node; break;
case V4SImode: eltype = V4SI_type_node; break;
case V4SFmode: eltype = V4SF_type_node; break;
case V2DImode: eltype = V2DI_type_node; break;
default: gcc_unreachable ();
}
}
if (k == 0 && !is_store)
return_type = eltype;
else
args = tree_cons (NULL_TREE, eltype, args);
}
ftype = build_function_type (return_type, args);
}
break;
case NEON_RESULTPAIR:
{
switch (insn_data[d->code].operand[1].mode)
{
case V8QImode: ftype = void_ftype_pv8qi_v8qi_v8qi; break;
case V4HImode: ftype = void_ftype_pv4hi_v4hi_v4hi; break;
case V2SImode: ftype = void_ftype_pv2si_v2si_v2si; break;
case V2SFmode: ftype = void_ftype_pv2sf_v2sf_v2sf; break;
case DImode: ftype = void_ftype_pdi_di_di; break;
case V16QImode: ftype = void_ftype_pv16qi_v16qi_v16qi; break;
case V8HImode: ftype = void_ftype_pv8hi_v8hi_v8hi; break;
case V4SImode: ftype = void_ftype_pv4si_v4si_v4si; break;
case V4SFmode: ftype = void_ftype_pv4sf_v4sf_v4sf; break;
case V2DImode: ftype = void_ftype_pv2di_v2di_v2di; break;
default: gcc_unreachable ();
}
}
break;
case NEON_REINTERP:
{
/* We iterate over 5 doubleword types, then 5 quadword
types. */
int rhs = d->mode % 5;
switch (insn_data[d->code].operand[0].mode)
{
case V8QImode: ftype = reinterp_ftype_dreg[0][rhs]; break;
case V4HImode: ftype = reinterp_ftype_dreg[1][rhs]; break;
case V2SImode: ftype = reinterp_ftype_dreg[2][rhs]; break;
case V2SFmode: ftype = reinterp_ftype_dreg[3][rhs]; break;
case DImode: ftype = reinterp_ftype_dreg[4][rhs]; break;
case V16QImode: ftype = reinterp_ftype_qreg[0][rhs]; break;
case V8HImode: ftype = reinterp_ftype_qreg[1][rhs]; break;
case V4SImode: ftype = reinterp_ftype_qreg[2][rhs]; break;
case V4SFmode: ftype = reinterp_ftype_qreg[3][rhs]; break;
case V2DImode: ftype = reinterp_ftype_qreg[4][rhs]; break;
default: gcc_unreachable ();
}
}
break;
default:
gcc_unreachable ();
}
gcc_assert (ftype != NULL);
sprintf (namebuf, "__builtin_neon_%s%s", d->name, modenames[d->mode]);
decl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, NULL,
NULL_TREE);
arm_builtin_decls[fcode] = decl;
}
}
#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
do \
{ \
if ((MASK) & insn_flags) \
{ \
tree bdecl; \
bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
BUILT_IN_MD, NULL, NULL_TREE); \
arm_builtin_decls[CODE] = bdecl; \
} \
} \
while (0)
struct builtin_description
{
const unsigned int mask;
const enum insn_code icode;
const char * const name;
const enum arm_builtins code;
const enum rtx_code comparison;
const unsigned int flag;
};
static const struct builtin_description bdesc_2arg[] =
{
#define IWMMXT_BUILTIN(code, string, builtin) \
{ FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
ARM_BUILTIN_##builtin, UNKNOWN, 0 },
IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS)
IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU)
#define IWMMXT_BUILTIN2(code, builtin) \
{ FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 },
IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
IWMMXT_BUILTIN2 (ashlv4hi3_di, WSLLH)
IWMMXT_BUILTIN2 (ashlv4hi3_iwmmxt, WSLLHI)
IWMMXT_BUILTIN2 (ashlv2si3_di, WSLLW)
IWMMXT_BUILTIN2 (ashlv2si3_iwmmxt, WSLLWI)
IWMMXT_BUILTIN2 (ashldi3_di, WSLLD)
IWMMXT_BUILTIN2 (ashldi3_iwmmxt, WSLLDI)
IWMMXT_BUILTIN2 (lshrv4hi3_di, WSRLH)
IWMMXT_BUILTIN2 (lshrv4hi3_iwmmxt, WSRLHI)
IWMMXT_BUILTIN2 (lshrv2si3_di, WSRLW)
IWMMXT_BUILTIN2 (lshrv2si3_iwmmxt, WSRLWI)
IWMMXT_BUILTIN2 (lshrdi3_di, WSRLD)
IWMMXT_BUILTIN2 (lshrdi3_iwmmxt, WSRLDI)
IWMMXT_BUILTIN2 (ashrv4hi3_di, WSRAH)
IWMMXT_BUILTIN2 (ashrv4hi3_iwmmxt, WSRAHI)
IWMMXT_BUILTIN2 (ashrv2si3_di, WSRAW)
IWMMXT_BUILTIN2 (ashrv2si3_iwmmxt, WSRAWI)
IWMMXT_BUILTIN2 (ashrdi3_di, WSRAD)
IWMMXT_BUILTIN2 (ashrdi3_iwmmxt, WSRADI)
IWMMXT_BUILTIN2 (rorv4hi3_di, WRORH)
IWMMXT_BUILTIN2 (rorv4hi3, WRORHI)
IWMMXT_BUILTIN2 (rorv2si3_di, WRORW)
IWMMXT_BUILTIN2 (rorv2si3, WRORWI)
IWMMXT_BUILTIN2 (rordi3_di, WRORD)
IWMMXT_BUILTIN2 (rordi3, WRORDI)
IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
};
static const struct builtin_description bdesc_1arg[] =
{
IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
};
/* Set up all the iWMMXt builtins. This is not called if
TARGET_IWMMXT is zero. */
static void
arm_init_iwmmxt_builtins (void)
{
const struct builtin_description * d;
size_t i;
tree endlink = void_list_node;
tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
tree int_ftype_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, integer_type_node, endlink));
tree v8qi_ftype_v8qi_v8qi_int
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree v4hi_ftype_v4hi_int
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_v2si_int
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_di_di
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
tree_cons (NULL_TREE,
long_long_integer_type_node,
endlink)));
tree di_ftype_di_int
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree di_ftype_di_int_int
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, long_long_integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree int_ftype_v8qi
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink));
tree int_ftype_v4hi
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink));
tree int_ftype_v2si
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink));
tree int_ftype_v8qi_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree int_ftype_v4hi_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree int_ftype_v2si_int
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v8qi_ftype_v8qi_int_int
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree v4hi_ftype_v4hi_int_int
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree v2si_ftype_v2si_int_int
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
/* Miscellaneous. */
tree v8qi_ftype_v4hi_v4hi
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
tree v4hi_ftype_v2si_v2si
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink)));
tree v2si_ftype_v4hi_v4hi
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
tree v2si_ftype_v8qi_v8qi
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink)));
tree v4hi_ftype_v4hi_di
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE,
long_long_integer_type_node,
endlink)));
tree v2si_ftype_v2si_di
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE,
long_long_integer_type_node,
endlink)));
tree void_ftype_int_int
= build_function_type (void_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree di_ftype_void
= build_function_type (long_long_unsigned_type_node, endlink);
tree di_ftype_v8qi
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink));
tree di_ftype_v4hi
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink));
tree di_ftype_v2si
= build_function_type (long_long_integer_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink));
tree v2si_ftype_v4hi
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink));
tree v4hi_ftype_v8qi
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink));
tree di_ftype_di_v4hi_v4hi
= build_function_type (long_long_unsigned_type_node,
tree_cons (NULL_TREE,
long_long_unsigned_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE,
V4HI_type_node,
endlink))));
for (i = 0; i < 5; i++) tree di_ftype_v4hi_v4hi
= build_function_type (long_long_unsigned_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
/* Normal vector binops. */
tree v8qi_ftype_v8qi_v8qi
= build_function_type (V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
tree_cons (NULL_TREE, V8QI_type_node,
endlink)));
tree v4hi_ftype_v4hi_v4hi
= build_function_type (V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
tree_cons (NULL_TREE, V4HI_type_node,
endlink)));
tree v2si_ftype_v2si_v2si
= build_function_type (V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
tree_cons (NULL_TREE, V2SI_type_node,
endlink)));
tree di_ftype_di_di
= build_function_type (long_long_unsigned_type_node,
tree_cons (NULL_TREE, long_long_unsigned_type_node,
tree_cons (NULL_TREE,
long_long_unsigned_type_node,
endlink)));
/* Add all builtins that are more or less simple operations on two
operands. */
for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
{ {
int j; /* Use one of the operands; the target can have a different mode for
for (j = 0; j < 5; j++) mask-generating compares. */
{ enum machine_mode mode;
reinterp_ftype_dreg[i][j] tree type;
= build_function_type_list (dreg_types[i], dreg_types[j], NULL);
reinterp_ftype_qreg[i][j]
= build_function_type_list (qreg_types[i], qreg_types[j], NULL);
}
}
for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++) if (d->name == 0)
{ continue;
neon_builtin_datum *d = &neon_builtin_data[i];
unsigned int j, codeidx = 0;
d->base_fcode = fcode; mode = insn_data[d->icode].operand[1].mode;
for (j = 0; j < T_MAX; j++) switch (mode)
{ {
const char* const modenames[] = { case V8QImode:
"v8qi", "v4hi", "v2si", "v2sf", "di", type = v8qi_ftype_v8qi_v8qi;
"v16qi", "v8hi", "v4si", "v4sf", "v2di" break;
}; case V4HImode:
char namebuf[60]; type = v4hi_ftype_v4hi_v4hi;
tree ftype = NULL; break;
enum insn_code icode; case V2SImode:
int is_load = 0, is_store = 0; type = v2si_ftype_v2si_v2si;
break;
if ((d->bits & (1 << j)) == 0) case DImode:
continue; type = di_ftype_di_di;
break;
icode = d->codes[codeidx++];
switch (d->itype)
{
case NEON_LOAD1:
case NEON_LOAD1LANE:
case NEON_LOADSTRUCT:
case NEON_LOADSTRUCTLANE:
is_load = 1;
/* Fall through. */
case NEON_STORE1:
case NEON_STORE1LANE:
case NEON_STORESTRUCT:
case NEON_STORESTRUCTLANE:
if (!is_load)
is_store = 1;
/* Fall through. */
case NEON_UNOP:
case NEON_BINOP:
case NEON_LOGICBINOP:
case NEON_SHIFTINSERT:
case NEON_TERNOP:
case NEON_GETLANE:
case NEON_SETLANE:
case NEON_CREATE:
case NEON_DUP:
case NEON_DUPLANE:
case NEON_SHIFTIMM:
case NEON_SHIFTACC:
case NEON_COMBINE:
case NEON_SPLIT:
case NEON_CONVERT:
case NEON_FIXCONV:
case NEON_LANEMUL:
case NEON_LANEMULL:
case NEON_LANEMULH:
case NEON_LANEMAC:
case NEON_SCALARMUL:
case NEON_SCALARMULL:
case NEON_SCALARMULH:
case NEON_SCALARMAC:
case NEON_SELECT:
case NEON_VTBL:
case NEON_VTBX:
{
int k;
tree return_type = void_type_node, args = void_list_node;
/* Build a function type directly from the insn_data for this
builtin. The build_function_type() function takes care of
removing duplicates for us. */
for (k = insn_data[icode].n_generator_args - 1; k >= 0; k--)
{
tree eltype;
if (is_load && k == 1)
{
/* Neon load patterns always have the memory operand
in the operand 1 position. */
gcc_assert (insn_data[icode].operand[k].predicate
== neon_struct_operand);
switch (1 << j)
{
case T_V8QI:
case T_V16QI:
eltype = const_intQI_pointer_node;
break;
case T_V4HI:
case T_V8HI:
eltype = const_intHI_pointer_node;
break;
case T_V2SI:
case T_V4SI:
eltype = const_intSI_pointer_node;
break;
case T_V2SF:
case T_V4SF:
eltype = const_float_pointer_node;
break;
case T_DI:
case T_V2DI:
eltype = const_intDI_pointer_node;
break;
default: gcc_unreachable ();
}
}
else if (is_store && k == 0)
{
/* Similarly, Neon store patterns use operand 0 as
the memory location to store to. */
gcc_assert (insn_data[icode].operand[k].predicate
== neon_struct_operand);
switch (1 << j)
{
case T_V8QI:
case T_V16QI:
eltype = intQI_pointer_node;
break;
case T_V4HI:
case T_V8HI:
eltype = intHI_pointer_node;
break;
case T_V2SI:
case T_V4SI:
eltype = intSI_pointer_node;
break;
case T_V2SF:
case T_V4SF:
eltype = float_pointer_node;
break;
case T_DI:
case T_V2DI:
eltype = intDI_pointer_node;
break;
default: gcc_unreachable ();
}
}
else
{
switch (insn_data[icode].operand[k].mode)
{
case VOIDmode: eltype = void_type_node; break;
/* Scalars. */
case QImode: eltype = neon_intQI_type_node; break;
case HImode: eltype = neon_intHI_type_node; break;
case SImode: eltype = neon_intSI_type_node; break;
case SFmode: eltype = neon_float_type_node; break;
case DImode: eltype = neon_intDI_type_node; break;
case TImode: eltype = intTI_type_node; break;
case EImode: eltype = intEI_type_node; break;
case OImode: eltype = intOI_type_node; break;
case CImode: eltype = intCI_type_node; break;
case XImode: eltype = intXI_type_node; break;
/* 64-bit vectors. */
case V8QImode: eltype = V8QI_type_node; break;
case V4HImode: eltype = V4HI_type_node; break;
case V2SImode: eltype = V2SI_type_node; break;
case V2SFmode: eltype = V2SF_type_node; break;
/* 128-bit vectors. */
case V16QImode: eltype = V16QI_type_node; break;
case V8HImode: eltype = V8HI_type_node; break;
case V4SImode: eltype = V4SI_type_node; break;
case V4SFmode: eltype = V4SF_type_node; break;
case V2DImode: eltype = V2DI_type_node; break;
default: gcc_unreachable ();
}
}
if (k == 0 && !is_store)
return_type = eltype;
else
args = tree_cons (NULL_TREE, eltype, args);
}
ftype = build_function_type (return_type, args);
}
break;
case NEON_RESULTPAIR:
{
switch (insn_data[icode].operand[1].mode)
{
case V8QImode: ftype = void_ftype_pv8qi_v8qi_v8qi; break;
case V4HImode: ftype = void_ftype_pv4hi_v4hi_v4hi; break;
case V2SImode: ftype = void_ftype_pv2si_v2si_v2si; break;
case V2SFmode: ftype = void_ftype_pv2sf_v2sf_v2sf; break;
case DImode: ftype = void_ftype_pdi_di_di; break;
case V16QImode: ftype = void_ftype_pv16qi_v16qi_v16qi; break;
case V8HImode: ftype = void_ftype_pv8hi_v8hi_v8hi; break;
case V4SImode: ftype = void_ftype_pv4si_v4si_v4si; break;
case V4SFmode: ftype = void_ftype_pv4sf_v4sf_v4sf; break;
case V2DImode: ftype = void_ftype_pv2di_v2di_v2di; break;
default: gcc_unreachable ();
}
}
break;
case NEON_REINTERP: default:
{ gcc_unreachable ();
/* We iterate over 5 doubleword types, then 5 quadword }
types. */
int rhs = j % 5;
switch (insn_data[icode].operand[0].mode)
{
case V8QImode: ftype = reinterp_ftype_dreg[0][rhs]; break;
case V4HImode: ftype = reinterp_ftype_dreg[1][rhs]; break;
case V2SImode: ftype = reinterp_ftype_dreg[2][rhs]; break;
case V2SFmode: ftype = reinterp_ftype_dreg[3][rhs]; break;
case DImode: ftype = reinterp_ftype_dreg[4][rhs]; break;
case V16QImode: ftype = reinterp_ftype_qreg[0][rhs]; break;
case V8HImode: ftype = reinterp_ftype_qreg[1][rhs]; break;
case V4SImode: ftype = reinterp_ftype_qreg[2][rhs]; break;
case V4SFmode: ftype = reinterp_ftype_qreg[3][rhs]; break;
case V2DImode: ftype = reinterp_ftype_qreg[4][rhs]; break;
default: gcc_unreachable ();
}
}
break;
default: def_mbuiltin (d->mask, d->name, type, d->code);
gcc_unreachable (); }
}
gcc_assert (ftype != NULL); /* Add the remaining MMX insns with somewhat more complicated types. */
#define iwmmx_mbuiltin(NAME, TYPE, CODE) \
def_mbuiltin (FL_IWMMXT, "__builtin_arm_" NAME, (TYPE), \
ARM_BUILTIN_ ## CODE)
iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
iwmmx_mbuiltin ("setwcx", void_ftype_int_int, SETWCX);
iwmmx_mbuiltin ("getwcx", int_ftype_int, GETWCX);
iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
iwmmx_mbuiltin ("wsadb", v2si_ftype_v8qi_v8qi, WSADB);
iwmmx_mbuiltin ("wsadh", v2si_ftype_v4hi_v4hi, WSADH);
iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGN);
iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
#undef iwmmx_mbuiltin
}
sprintf (namebuf, "__builtin_neon_%s%s", d->name, modenames[j]); static void
arm_init_tls_builtins (void)
{
tree ftype, decl;
add_builtin_function (namebuf, ftype, fcode++, BUILT_IN_MD, NULL, ftype = build_function_type (ptr_type_node, void_list_node);
NULL_TREE); decl = add_builtin_function ("__builtin_thread_pointer", ftype,
} ARM_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
} NULL, NULL_TREE);
TREE_NOTHROW (decl) = 1;
TREE_READONLY (decl) = 1;
arm_builtin_decls[ARM_BUILTIN_THREAD_POINTER] = decl;
} }
static void static void
...@@ -19095,6 +19278,17 @@ arm_init_builtins (void) ...@@ -19095,6 +19278,17 @@ arm_init_builtins (void)
arm_init_fp16_builtins (); arm_init_fp16_builtins ();
} }
/* Return the ARM builtin for CODE. */
static tree
arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
if (code >= ARM_BUILTIN_MAX)
return error_mark_node;
return arm_builtin_decls[code];
}
/* Implement TARGET_INVALID_PARAMETER_TYPE. */ /* Implement TARGET_INVALID_PARAMETER_TYPE. */
static const char * static const char *
...@@ -19246,58 +19440,6 @@ arm_expand_unop_builtin (enum insn_code icode, ...@@ -19246,58 +19440,6 @@ arm_expand_unop_builtin (enum insn_code icode,
return target; return target;
} }
static int
neon_builtin_compare (const void *a, const void *b)
{
const neon_builtin_datum *const key = (const neon_builtin_datum *) a;
const neon_builtin_datum *const memb = (const neon_builtin_datum *) b;
unsigned int soughtcode = key->base_fcode;
if (soughtcode >= memb->base_fcode
&& soughtcode < memb->base_fcode + memb->num_vars)
return 0;
else if (soughtcode < memb->base_fcode)
return -1;
else
return 1;
}
static enum insn_code
locate_neon_builtin_icode (int fcode, neon_itype *itype,
enum neon_builtin_type_bits *type_bit)
{
neon_builtin_datum key
= { NULL, (neon_itype) 0, 0, { CODE_FOR_nothing }, 0, 0 };
neon_builtin_datum *found;
int idx, type, ntypes;
key.base_fcode = fcode;
found = (neon_builtin_datum *)
bsearch (&key, &neon_builtin_data[0], ARRAY_SIZE (neon_builtin_data),
sizeof (neon_builtin_data[0]), neon_builtin_compare);
gcc_assert (found);
idx = fcode - (int) found->base_fcode;
gcc_assert (idx >= 0 && idx < T_MAX && idx < (int)found->num_vars);
if (itype)
*itype = found->itype;
if (type_bit)
{
ntypes = 0;
for (type = 0; type < T_MAX; type++)
if (found->bits & (1 << type))
{
if (ntypes == idx)
break;
ntypes++;
}
gcc_assert (type < T_MAX);
*type_bit = (enum neon_builtin_type_bits) (1 << type);
}
return found->codes[idx];
}
typedef enum { typedef enum {
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
NEON_ARG_CONSTANT, NEON_ARG_CONSTANT,
...@@ -19311,14 +19453,14 @@ typedef enum { ...@@ -19311,14 +19453,14 @@ typedef enum {
and return an expression for the accessed memory. and return an expression for the accessed memory.
The intrinsic function operates on a block of registers that has The intrinsic function operates on a block of registers that has
mode REG_MODE. This block contains vectors of type TYPE_BIT. mode REG_MODE. This block contains vectors of type TYPE_MODE.
The function references the memory at EXP in mode MEM_MODE; The function references the memory at EXP in mode MEM_MODE;
this mode may be BLKmode if no more suitable mode is available. */ this mode may be BLKmode if no more suitable mode is available. */
static tree static tree
neon_dereference_pointer (tree exp, enum machine_mode mem_mode, neon_dereference_pointer (tree exp, enum machine_mode mem_mode,
enum machine_mode reg_mode, enum machine_mode reg_mode,
enum neon_builtin_type_bits type_bit) neon_builtin_type_mode type_mode)
{ {
HOST_WIDE_INT reg_size, vector_size, nvectors, nelems; HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
tree elem_type, upper_bound, array_type; tree elem_type, upper_bound, array_type;
...@@ -19327,8 +19469,8 @@ neon_dereference_pointer (tree exp, enum machine_mode mem_mode, ...@@ -19327,8 +19469,8 @@ neon_dereference_pointer (tree exp, enum machine_mode mem_mode,
reg_size = GET_MODE_SIZE (reg_mode); reg_size = GET_MODE_SIZE (reg_mode);
/* Work out the size of each vector in bytes. */ /* Work out the size of each vector in bytes. */
gcc_assert (type_bit & (T_DREG | T_QREG)); gcc_assert (TYPE_MODE_BIT (type_mode) & (TB_DREG | TB_QREG));
vector_size = (type_bit & T_QREG ? 16 : 8); vector_size = (TYPE_MODE_BIT (type_mode) & TB_QREG ? 16 : 8);
/* Work out how many vectors there are. */ /* Work out how many vectors there are. */
gcc_assert (reg_size % vector_size == 0); gcc_assert (reg_size % vector_size == 0);
...@@ -19359,7 +19501,7 @@ neon_dereference_pointer (tree exp, enum machine_mode mem_mode, ...@@ -19359,7 +19501,7 @@ neon_dereference_pointer (tree exp, enum machine_mode mem_mode,
/* Expand a Neon builtin. */ /* Expand a Neon builtin. */
static rtx static rtx
arm_expand_neon_args (rtx target, int icode, int have_retval, arm_expand_neon_args (rtx target, int icode, int have_retval,
enum neon_builtin_type_bits type_bit, neon_builtin_type_mode type_mode,
tree exp, ...) tree exp, ...)
{ {
va_list ap; va_list ap;
...@@ -19395,7 +19537,7 @@ arm_expand_neon_args (rtx target, int icode, int have_retval, ...@@ -19395,7 +19537,7 @@ arm_expand_neon_args (rtx target, int icode, int have_retval,
{ {
other_mode = insn_data[icode].operand[1 - opno].mode; other_mode = insn_data[icode].operand[1 - opno].mode;
arg[argc] = neon_dereference_pointer (arg[argc], mode[argc], arg[argc] = neon_dereference_pointer (arg[argc], mode[argc],
other_mode, type_bit); other_mode, type_mode);
} }
op[argc] = expand_normal (arg[argc]); op[argc] = expand_normal (arg[argc]);
...@@ -19505,16 +19647,17 @@ arm_expand_neon_args (rtx target, int icode, int have_retval, ...@@ -19505,16 +19647,17 @@ arm_expand_neon_args (rtx target, int icode, int have_retval,
static rtx static rtx
arm_expand_neon_builtin (int fcode, tree exp, rtx target) arm_expand_neon_builtin (int fcode, tree exp, rtx target)
{ {
neon_itype itype; neon_builtin_datum *d = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_BASE];
enum neon_builtin_type_bits type_bit; neon_itype itype = d->itype;
enum insn_code icode = locate_neon_builtin_icode (fcode, &itype, &type_bit); enum insn_code icode = d->code;
neon_builtin_type_mode type_mode = d->mode;
switch (itype) switch (itype)
{ {
case NEON_UNOP: case NEON_UNOP:
case NEON_CONVERT: case NEON_CONVERT:
case NEON_DUPLANE: case NEON_DUPLANE:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_STOP); NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_STOP);
case NEON_BINOP: case NEON_BINOP:
...@@ -19524,89 +19667,89 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target) ...@@ -19524,89 +19667,89 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target)
case NEON_SCALARMULH: case NEON_SCALARMULH:
case NEON_SHIFTINSERT: case NEON_SHIFTINSERT:
case NEON_LOGICBINOP: case NEON_LOGICBINOP:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
NEON_ARG_STOP); NEON_ARG_STOP);
case NEON_TERNOP: case NEON_TERNOP:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
NEON_ARG_CONSTANT, NEON_ARG_STOP); NEON_ARG_CONSTANT, NEON_ARG_STOP);
case NEON_GETLANE: case NEON_GETLANE:
case NEON_FIXCONV: case NEON_FIXCONV:
case NEON_SHIFTIMM: case NEON_SHIFTIMM:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_CONSTANT, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_CONSTANT,
NEON_ARG_STOP); NEON_ARG_STOP);
case NEON_CREATE: case NEON_CREATE:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_STOP); NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
case NEON_DUP: case NEON_DUP:
case NEON_SPLIT: case NEON_SPLIT:
case NEON_REINTERP: case NEON_REINTERP:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_STOP); NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
case NEON_COMBINE: case NEON_COMBINE:
case NEON_VTBL: case NEON_VTBL:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_STOP); NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
case NEON_RESULTPAIR: case NEON_RESULTPAIR:
return arm_expand_neon_args (target, icode, 0, type_bit, exp, return arm_expand_neon_args (target, icode, 0, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
NEON_ARG_STOP); NEON_ARG_STOP);
case NEON_LANEMUL: case NEON_LANEMUL:
case NEON_LANEMULL: case NEON_LANEMULL:
case NEON_LANEMULH: case NEON_LANEMULH:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
NEON_ARG_CONSTANT, NEON_ARG_STOP); NEON_ARG_CONSTANT, NEON_ARG_STOP);
case NEON_LANEMAC: case NEON_LANEMAC:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
NEON_ARG_CONSTANT, NEON_ARG_CONSTANT, NEON_ARG_STOP); NEON_ARG_CONSTANT, NEON_ARG_CONSTANT, NEON_ARG_STOP);
case NEON_SHIFTACC: case NEON_SHIFTACC:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
NEON_ARG_CONSTANT, NEON_ARG_STOP); NEON_ARG_CONSTANT, NEON_ARG_STOP);
case NEON_SCALARMAC: case NEON_SCALARMAC:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
NEON_ARG_CONSTANT, NEON_ARG_STOP); NEON_ARG_CONSTANT, NEON_ARG_STOP);
case NEON_SELECT: case NEON_SELECT:
case NEON_VTBX: case NEON_VTBX:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
NEON_ARG_STOP); NEON_ARG_STOP);
case NEON_LOAD1: case NEON_LOAD1:
case NEON_LOADSTRUCT: case NEON_LOADSTRUCT:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_MEMORY, NEON_ARG_STOP); NEON_ARG_MEMORY, NEON_ARG_STOP);
case NEON_LOAD1LANE: case NEON_LOAD1LANE:
case NEON_LOADSTRUCTLANE: case NEON_LOADSTRUCTLANE:
return arm_expand_neon_args (target, icode, 1, type_bit, exp, return arm_expand_neon_args (target, icode, 1, type_mode, exp,
NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
NEON_ARG_STOP); NEON_ARG_STOP);
case NEON_STORE1: case NEON_STORE1:
case NEON_STORESTRUCT: case NEON_STORESTRUCT:
return arm_expand_neon_args (target, icode, 0, type_bit, exp, return arm_expand_neon_args (target, icode, 0, type_mode, exp,
NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_STOP); NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
case NEON_STORE1LANE: case NEON_STORE1LANE:
case NEON_STORESTRUCTLANE: case NEON_STORESTRUCTLANE:
return arm_expand_neon_args (target, icode, 0, type_bit, exp, return arm_expand_neon_args (target, icode, 0, type_mode, exp,
NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
NEON_ARG_STOP); NEON_ARG_STOP);
} }
......
...@@ -2249,178 +2249,6 @@ extern int making_const_table; ...@@ -2249,178 +2249,6 @@ extern int making_const_table;
: arm_gen_return_addr_mask ()) : arm_gen_return_addr_mask ())
/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have
symbolic names defined here (which would require too much duplication).
FIXME? */
enum arm_builtins
{
ARM_BUILTIN_GETWCX,
ARM_BUILTIN_SETWCX,
ARM_BUILTIN_WZERO,
ARM_BUILTIN_WAVG2BR,
ARM_BUILTIN_WAVG2HR,
ARM_BUILTIN_WAVG2B,
ARM_BUILTIN_WAVG2H,
ARM_BUILTIN_WACCB,
ARM_BUILTIN_WACCH,
ARM_BUILTIN_WACCW,
ARM_BUILTIN_WMACS,
ARM_BUILTIN_WMACSZ,
ARM_BUILTIN_WMACU,
ARM_BUILTIN_WMACUZ,
ARM_BUILTIN_WSADB,
ARM_BUILTIN_WSADBZ,
ARM_BUILTIN_WSADH,
ARM_BUILTIN_WSADHZ,
ARM_BUILTIN_WALIGN,
ARM_BUILTIN_TMIA,
ARM_BUILTIN_TMIAPH,
ARM_BUILTIN_TMIABB,
ARM_BUILTIN_TMIABT,
ARM_BUILTIN_TMIATB,
ARM_BUILTIN_TMIATT,
ARM_BUILTIN_TMOVMSKB,
ARM_BUILTIN_TMOVMSKH,
ARM_BUILTIN_TMOVMSKW,
ARM_BUILTIN_TBCSTB,
ARM_BUILTIN_TBCSTH,
ARM_BUILTIN_TBCSTW,
ARM_BUILTIN_WMADDS,
ARM_BUILTIN_WMADDU,
ARM_BUILTIN_WPACKHSS,
ARM_BUILTIN_WPACKWSS,
ARM_BUILTIN_WPACKDSS,
ARM_BUILTIN_WPACKHUS,
ARM_BUILTIN_WPACKWUS,
ARM_BUILTIN_WPACKDUS,
ARM_BUILTIN_WADDB,
ARM_BUILTIN_WADDH,
ARM_BUILTIN_WADDW,
ARM_BUILTIN_WADDSSB,
ARM_BUILTIN_WADDSSH,
ARM_BUILTIN_WADDSSW,
ARM_BUILTIN_WADDUSB,
ARM_BUILTIN_WADDUSH,
ARM_BUILTIN_WADDUSW,
ARM_BUILTIN_WSUBB,
ARM_BUILTIN_WSUBH,
ARM_BUILTIN_WSUBW,
ARM_BUILTIN_WSUBSSB,
ARM_BUILTIN_WSUBSSH,
ARM_BUILTIN_WSUBSSW,
ARM_BUILTIN_WSUBUSB,
ARM_BUILTIN_WSUBUSH,
ARM_BUILTIN_WSUBUSW,
ARM_BUILTIN_WAND,
ARM_BUILTIN_WANDN,
ARM_BUILTIN_WOR,
ARM_BUILTIN_WXOR,
ARM_BUILTIN_WCMPEQB,
ARM_BUILTIN_WCMPEQH,
ARM_BUILTIN_WCMPEQW,
ARM_BUILTIN_WCMPGTUB,
ARM_BUILTIN_WCMPGTUH,
ARM_BUILTIN_WCMPGTUW,
ARM_BUILTIN_WCMPGTSB,
ARM_BUILTIN_WCMPGTSH,
ARM_BUILTIN_WCMPGTSW,
ARM_BUILTIN_TEXTRMSB,
ARM_BUILTIN_TEXTRMSH,
ARM_BUILTIN_TEXTRMSW,
ARM_BUILTIN_TEXTRMUB,
ARM_BUILTIN_TEXTRMUH,
ARM_BUILTIN_TEXTRMUW,
ARM_BUILTIN_TINSRB,
ARM_BUILTIN_TINSRH,
ARM_BUILTIN_TINSRW,
ARM_BUILTIN_WMAXSW,
ARM_BUILTIN_WMAXSH,
ARM_BUILTIN_WMAXSB,
ARM_BUILTIN_WMAXUW,
ARM_BUILTIN_WMAXUH,
ARM_BUILTIN_WMAXUB,
ARM_BUILTIN_WMINSW,
ARM_BUILTIN_WMINSH,
ARM_BUILTIN_WMINSB,
ARM_BUILTIN_WMINUW,
ARM_BUILTIN_WMINUH,
ARM_BUILTIN_WMINUB,
ARM_BUILTIN_WMULUM,
ARM_BUILTIN_WMULSM,
ARM_BUILTIN_WMULUL,
ARM_BUILTIN_PSADBH,
ARM_BUILTIN_WSHUFH,
ARM_BUILTIN_WSLLH,
ARM_BUILTIN_WSLLW,
ARM_BUILTIN_WSLLD,
ARM_BUILTIN_WSRAH,
ARM_BUILTIN_WSRAW,
ARM_BUILTIN_WSRAD,
ARM_BUILTIN_WSRLH,
ARM_BUILTIN_WSRLW,
ARM_BUILTIN_WSRLD,
ARM_BUILTIN_WRORH,
ARM_BUILTIN_WRORW,
ARM_BUILTIN_WRORD,
ARM_BUILTIN_WSLLHI,
ARM_BUILTIN_WSLLWI,
ARM_BUILTIN_WSLLDI,
ARM_BUILTIN_WSRAHI,
ARM_BUILTIN_WSRAWI,
ARM_BUILTIN_WSRADI,
ARM_BUILTIN_WSRLHI,
ARM_BUILTIN_WSRLWI,
ARM_BUILTIN_WSRLDI,
ARM_BUILTIN_WRORHI,
ARM_BUILTIN_WRORWI,
ARM_BUILTIN_WRORDI,
ARM_BUILTIN_WUNPCKIHB,
ARM_BUILTIN_WUNPCKIHH,
ARM_BUILTIN_WUNPCKIHW,
ARM_BUILTIN_WUNPCKILB,
ARM_BUILTIN_WUNPCKILH,
ARM_BUILTIN_WUNPCKILW,
ARM_BUILTIN_WUNPCKEHSB,
ARM_BUILTIN_WUNPCKEHSH,
ARM_BUILTIN_WUNPCKEHSW,
ARM_BUILTIN_WUNPCKEHUB,
ARM_BUILTIN_WUNPCKEHUH,
ARM_BUILTIN_WUNPCKEHUW,
ARM_BUILTIN_WUNPCKELSB,
ARM_BUILTIN_WUNPCKELSH,
ARM_BUILTIN_WUNPCKELSW,
ARM_BUILTIN_WUNPCKELUB,
ARM_BUILTIN_WUNPCKELUH,
ARM_BUILTIN_WUNPCKELUW,
ARM_BUILTIN_THREAD_POINTER,
ARM_BUILTIN_NEON_BASE,
ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE /* FIXME: Wrong! */
};
/* Do not emit .note.GNU-stack by default. */ /* Do not emit .note.GNU-stack by default. */
#ifndef NEED_INDICATE_EXEC_STACK #ifndef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 0 #define NEED_INDICATE_EXEC_STACK 0
......
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