From: rearnsha Date: Mon, 18 Apr 2011 14:01:13 +0000 (+0000) Subject: Jie Zhang X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=38afa546b4ba64ea18d171fd649084ba26cb8e44;p=pf3gnuchains%2Fgcc-fork.git Jie Zhang Richard Earnshaw * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172646 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e6dda63e25..6e126426101 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2011-04-18 Jie Zhang + Richard Earnshaw + + * 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 * tree.c (upper_bound_in_type): Build properly canonicalized diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index aa13e2be297..722a3715ea5 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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_unop_builtin (enum insn_code, tree, rtx, 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 rtx emit_set_insn (rtx, rtx); static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, @@ -409,6 +410,8 @@ static const struct default_options arm_option_optimization_table[] = #define TARGET_INIT_BUILTINS arm_init_builtins #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN arm_expand_builtin +#undef TARGET_BUILTIN_DECL +#define TARGET_BUILTIN_DECL arm_builtin_decl #undef TARGET_INIT_LIBFUNCS #define TARGET_INIT_LIBFUNCS arm_init_libfuncs @@ -17763,892 +17766,582 @@ arm_debugger_arg_offset (int value, rtx addr) return value; } -#define def_mbuiltin(MASK, NAME, TYPE, CODE) \ - do \ - { \ - if ((MASK) & insn_flags) \ - add_builtin_function ((NAME), (TYPE), (CODE), \ - BUILT_IN_MD, NULL, NULL_TREE); \ - } \ - while (0) +typedef enum { + T_V8QI, + T_V4HI, + T_V2SI, + T_V2SF, + T_DI, + T_V16QI, + 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 -{ - 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; -}; +#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 -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 }, +#define UP(X) X##_UP - 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) +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; -#define IWMMXT_BUILTIN2(code, builtin) \ - { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 }, +typedef struct { + 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) - 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) -}; +#define CF(N,X) CODE_FOR_neon_##N##X -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) - 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) + 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 + +/* 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 - not called if TARGET_IWMMXT is zero. */ +static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX]; static void -arm_init_iwmmxt_builtins (void) +arm_init_neon_builtins (void) { - const struct builtin_description * d; - size_t i; - tree endlink = void_list_node; + unsigned int i, fcode; + tree decl; - 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 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 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)))); - - 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))); + tree intQI_pointer_node; + tree intHI_pointer_node; + tree intSI_pointer_node; + tree intDI_pointer_node; + tree float_pointer_node; - /* 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++) - { - /* Use one of the operands; the target can have a different mode for - mask-generating compares. */ - enum machine_mode mode; - tree type; + tree const_intQI_node; + tree const_intHI_node; + tree const_intSI_node; + tree const_intDI_node; + tree const_float_node; - if (d->name == 0) - continue; + 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; - 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) - { - case V8QImode: - type = v8qi_ftype_v8qi_v8qi; - 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; + tree intUQI_type_node; + tree intUHI_type_node; + tree intUSI_type_node; + tree intUDI_type_node; - default: - gcc_unreachable (); - } + tree intEI_type_node; + 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. */ - def_mbuiltin (FL_IWMMXT, "__builtin_arm_wzero", di_ftype_void, ARM_BUILTIN_WZERO); - def_mbuiltin (FL_IWMMXT, "__builtin_arm_setwcx", void_ftype_int_int, ARM_BUILTIN_SETWCX); - def_mbuiltin (FL_IWMMXT, "__builtin_arm_getwcx", int_ftype_int, ARM_BUILTIN_GETWCX); - - def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSLLH); - def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllw", v2si_ftype_v2si_di, ARM_BUILTIN_WSLLW); - def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslld", di_ftype_di_di, ARM_BUILTIN_WSLLD); - def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSLLHI); - def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSLLWI); - 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); -} + 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; -static void -arm_init_tls_builtins (void) -{ - 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]; + 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, and pointers to values of such types, so we can detect them later. */ @@ -18807,268 +18500,758 @@ arm_init_neon_builtins (void) dreg_types[3] = V2SF_type_node; dreg_types[4] = neon_intDI_type_node; - qreg_types[0] = V16QI_type_node; - qreg_types[1] = V8HI_type_node; - qreg_types[2] = V4SI_type_node; - qreg_types[3] = V4SF_type_node; - qreg_types[4] = V2DI_type_node; + qreg_types[0] = V16QI_type_node; + qreg_types[1] = V8HI_type_node; + qreg_types[2] = V4SI_type_node; + qreg_types[3] = V4SF_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; - 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); - } - } + /* Use one of the operands; the target can have a different mode for + mask-generating compares. */ + enum machine_mode mode; + tree type; - for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++) - { - neon_builtin_datum *d = &neon_builtin_data[i]; - unsigned int j, codeidx = 0; + if (d->name == 0) + continue; - 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[] = { - "v8qi", "v4hi", "v2si", "v2sf", "di", - "v16qi", "v8hi", "v4si", "v4sf", "v2di" - }; - char namebuf[60]; - tree ftype = NULL; - enum insn_code icode; - int is_load = 0, is_store = 0; - - if ((d->bits & (1 << j)) == 0) - continue; - - 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 V8QImode: + type = v8qi_ftype_v8qi_v8qi; + 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; - case NEON_REINTERP: - { - /* 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: + gcc_unreachable (); + } - default: - gcc_unreachable (); - } + def_mbuiltin (d->mask, d->name, type, d->code); + } - 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, - NULL_TREE); - } - } + 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; + arm_builtin_decls[ARM_BUILTIN_THREAD_POINTER] = decl; } static void @@ -19095,6 +19278,17 @@ arm_init_builtins (void) 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. */ static const char * @@ -19246,58 +19440,6 @@ arm_expand_unop_builtin (enum insn_code icode, 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 { NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, @@ -19311,14 +19453,14 @@ typedef enum { and return an expression for the accessed memory. 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; this mode may be BLKmode if no more suitable mode is available. */ static tree neon_dereference_pointer (tree exp, enum machine_mode mem_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; tree elem_type, upper_bound, array_type; @@ -19327,8 +19469,8 @@ neon_dereference_pointer (tree exp, enum machine_mode mem_mode, reg_size = GET_MODE_SIZE (reg_mode); /* Work out the size of each vector in bytes. */ - gcc_assert (type_bit & (T_DREG | T_QREG)); - vector_size = (type_bit & T_QREG ? 16 : 8); + gcc_assert (TYPE_MODE_BIT (type_mode) & (TB_DREG | TB_QREG)); + vector_size = (TYPE_MODE_BIT (type_mode) & TB_QREG ? 16 : 8); /* Work out how many vectors there are. */ gcc_assert (reg_size % vector_size == 0); @@ -19359,7 +19501,7 @@ neon_dereference_pointer (tree exp, enum machine_mode mem_mode, /* Expand a Neon builtin. */ static rtx 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, ...) { va_list ap; @@ -19395,7 +19537,7 @@ arm_expand_neon_args (rtx target, int icode, int have_retval, { other_mode = insn_data[icode].operand[1 - opno].mode; arg[argc] = neon_dereference_pointer (arg[argc], mode[argc], - other_mode, type_bit); + other_mode, type_mode); } op[argc] = expand_normal (arg[argc]); @@ -19505,16 +19647,17 @@ arm_expand_neon_args (rtx target, int icode, int have_retval, static rtx arm_expand_neon_builtin (int fcode, tree exp, rtx target) { - neon_itype itype; - enum neon_builtin_type_bits type_bit; - enum insn_code icode = locate_neon_builtin_icode (fcode, &itype, &type_bit); + neon_builtin_datum *d = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_BASE]; + neon_itype itype = d->itype; + enum insn_code icode = d->code; + neon_builtin_type_mode type_mode = d->mode; switch (itype) { case NEON_UNOP: case NEON_CONVERT: 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); case NEON_BINOP: @@ -19524,89 +19667,89 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target) case NEON_SCALARMULH: case NEON_SHIFTINSERT: 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_STOP); 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_CONSTANT, NEON_ARG_STOP); case NEON_GETLANE: case NEON_FIXCONV: 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_STOP); 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); case NEON_DUP: case NEON_SPLIT: 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); case NEON_COMBINE: 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); 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_STOP); case NEON_LANEMUL: case NEON_LANEMULL: 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_CONSTANT, NEON_ARG_STOP); 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_CONSTANT, NEON_ARG_CONSTANT, NEON_ARG_STOP); 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_CONSTANT, NEON_ARG_STOP); 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_CONSTANT, NEON_ARG_STOP); case NEON_SELECT: 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_STOP); case NEON_LOAD1: 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); case NEON_LOAD1LANE: 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_STOP); case NEON_STORE1: 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); case NEON_STORE1LANE: 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_STOP); } diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index a7718fa5318..e45b9274323 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2249,178 +2249,6 @@ extern int making_const_table; : 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. */ #ifndef NEED_INDICATE_EXEC_STACK #define NEED_INDICATE_EXEC_STACK 0