From patchwork Thu Dec 23 13:50:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Zhang X-Patchwork-Id: 76516 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 11E00B70CD for ; Fri, 24 Dec 2010 00:50:41 +1100 (EST) Received: (qmail 15381 invoked by alias); 23 Dec 2010 13:50:39 -0000 Received: (qmail 15335 invoked by uid 22791); 23 Dec 2010 13:50:31 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 23 Dec 2010 13:50:13 +0000 Received: (qmail 11133 invoked from network); 23 Dec 2010 13:50:11 -0000 Received: from unknown (HELO ?192.168.0.101?) (jie@127.0.0.2) by mail.codesourcery.com with ESMTPA; 23 Dec 2010 13:50:11 -0000 Message-ID: <4D135389.9000903@codesourcery.com> Date: Thu, 23 Dec 2010 21:50:01 +0800 From: Jie Zhang User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101213 Lightning/1.0b2 Icedove/3.1.7 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: PING [ARM] [2/3] Rearrange builtin code X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org http://gcc.gnu.org/ml/gcc-patches/2010-10/msg00853.html Just updated for the latest trunk. Regards, * config/arm/arm.h (enum arm_builtins): Move to ... * config/arm/arm.c: ... here. And rearrange builtin code. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3f83cf0..549b116 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -17698,610 +17698,128 @@ 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 +} neon_builtin_mode; -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_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[] = -{ - 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) -}; +#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} -/* Set up all the iWMMXt builtins. This is - not called if TARGET_IWMMXT is zero. */ +/* 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 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)))); - - 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++) - { - /* Use one of the operands; the target can have a different mode for - mask-generating compares. */ - enum machine_mode mode; - tree type; - - if (d->name == 0) - continue; - - mode = insn_data[d->icode].operand[1].mode; - - 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; - - default: - gcc_unreachable (); - } - - def_mbuiltin (d->mask, d->name, type, d->code); - } - - /* 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); -} - -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; -} - -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 -} neon_builtin_mode; - -#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 - -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 neon_builtin_mode mode; - const enum insn_code code; - unsigned int 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), 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[] = +static neon_builtin_datum neon_builtin_data[] = { VAR10 (BINOP, vadd, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di), @@ -18497,6 +18015,179 @@ static neon_builtin_datum neon_builtin_data[] = #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 /* FIXME: Wrong! */ +}; + + static void arm_init_neon_builtins (void) { @@ -18649,341 +18340,822 @@ arm_init_neon_builtins (void) V2DI_type_node = build_vector_type_for_mode (neon_intDI_type_node, V2DImode); - /* Unsigned integer types for various mode sizes. */ - intUQI_type_node = make_unsigned_type (GET_MODE_PRECISION (QImode)); - intUHI_type_node = make_unsigned_type (GET_MODE_PRECISION (HImode)); - intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode)); - intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode)); + /* Unsigned integer types for various mode sizes. */ + intUQI_type_node = make_unsigned_type (GET_MODE_PRECISION (QImode)); + intUHI_type_node = make_unsigned_type (GET_MODE_PRECISION (HImode)); + intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode)); + intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode)); + + (*lang_hooks.types.register_builtin_type) (intUQI_type_node, + "__builtin_neon_uqi"); + (*lang_hooks.types.register_builtin_type) (intUHI_type_node, + "__builtin_neon_uhi"); + (*lang_hooks.types.register_builtin_type) (intUSI_type_node, + "__builtin_neon_usi"); + (*lang_hooks.types.register_builtin_type) (intUDI_type_node, + "__builtin_neon_udi"); + + /* Opaque integer types for structures of vectors. */ + intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode)); + intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode)); + intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode)); + intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode)); + + (*lang_hooks.types.register_builtin_type) (intTI_type_node, + "__builtin_neon_ti"); + (*lang_hooks.types.register_builtin_type) (intEI_type_node, + "__builtin_neon_ei"); + (*lang_hooks.types.register_builtin_type) (intOI_type_node, + "__builtin_neon_oi"); + (*lang_hooks.types.register_builtin_type) (intCI_type_node, + "__builtin_neon_ci"); + (*lang_hooks.types.register_builtin_type) (intXI_type_node, + "__builtin_neon_xi"); + + /* Pointers to vector types. */ + V8QI_pointer_node = build_pointer_type (V8QI_type_node); + V4HI_pointer_node = build_pointer_type (V4HI_type_node); + V2SI_pointer_node = build_pointer_type (V2SI_type_node); + V2SF_pointer_node = build_pointer_type (V2SF_type_node); + V16QI_pointer_node = build_pointer_type (V16QI_type_node); + V8HI_pointer_node = build_pointer_type (V8HI_type_node); + V4SI_pointer_node = build_pointer_type (V4SI_type_node); + V4SF_pointer_node = build_pointer_type (V4SF_type_node); + V2DI_pointer_node = build_pointer_type (V2DI_type_node); + + /* Operations which return results as pairs. */ + void_ftype_pv8qi_v8qi_v8qi = + build_function_type_list (void_type_node, V8QI_pointer_node, V8QI_type_node, + V8QI_type_node, NULL); + void_ftype_pv4hi_v4hi_v4hi = + build_function_type_list (void_type_node, V4HI_pointer_node, V4HI_type_node, + V4HI_type_node, NULL); + void_ftype_pv2si_v2si_v2si = + build_function_type_list (void_type_node, V2SI_pointer_node, V2SI_type_node, + V2SI_type_node, NULL); + void_ftype_pv2sf_v2sf_v2sf = + build_function_type_list (void_type_node, V2SF_pointer_node, V2SF_type_node, + V2SF_type_node, NULL); + void_ftype_pdi_di_di = + build_function_type_list (void_type_node, intDI_pointer_node, + neon_intDI_type_node, neon_intDI_type_node, NULL); + void_ftype_pv16qi_v16qi_v16qi = + build_function_type_list (void_type_node, V16QI_pointer_node, + V16QI_type_node, V16QI_type_node, NULL); + void_ftype_pv8hi_v8hi_v8hi = + build_function_type_list (void_type_node, V8HI_pointer_node, V8HI_type_node, + V8HI_type_node, NULL); + void_ftype_pv4si_v4si_v4si = + build_function_type_list (void_type_node, V4SI_pointer_node, V4SI_type_node, + V4SI_type_node, NULL); + void_ftype_pv4sf_v4sf_v4sf = + build_function_type_list (void_type_node, V4SF_pointer_node, V4SF_type_node, + V4SF_type_node, NULL); + void_ftype_pv2di_v2di_v2di = + build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node, + V2DI_type_node, NULL); + + dreg_types[0] = V8QI_type_node; + dreg_types[1] = V4HI_type_node; + dreg_types[2] = V2SI_type_node; + 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; + + 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; i < ARRAY_SIZE (neon_builtin_data); i++) + { + neon_builtin_datum *d = &neon_builtin_data[i]; + const char* const modenames[] = { + "v8qi", "v4hi", "v2si", "v2sf", "di", + "v16qi", "v8hi", "v4si", "v4sf", "v2di" + }; + char namebuf[60]; + tree ftype = NULL; + int is_load = 0, is_store = 0; + + 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_operands - 1; k >= 0; k--) + { + tree eltype; + + if (is_load && k == 1) + { + /* Neon load patterns always have the memory operand + (a SImode pointer) in the operand 1 position. We + want a const pointer to the element type in that + position. */ + gcc_assert (insn_data[d->code].operand[k].mode == SImode); + + 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 (a SImode pointer). + Use a pointer to the element type of the store in + that position. */ + gcc_assert (insn_data[d->code].operand[k].mode == SImode); + + 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]); + + add_builtin_function (namebuf, ftype, fcode++, BUILT_IN_MD, NULL, + NULL_TREE); + } +} + +#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) + +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 }, - (*lang_hooks.types.register_builtin_type) (intUQI_type_node, - "__builtin_neon_uqi"); - (*lang_hooks.types.register_builtin_type) (intUHI_type_node, - "__builtin_neon_uhi"); - (*lang_hooks.types.register_builtin_type) (intUSI_type_node, - "__builtin_neon_usi"); - (*lang_hooks.types.register_builtin_type) (intUDI_type_node, - "__builtin_neon_udi"); + 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) +}; - /* Opaque integer types for structures of vectors. */ - intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode)); - intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode)); - intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode)); - intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode)); +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) +}; - (*lang_hooks.types.register_builtin_type) (intTI_type_node, - "__builtin_neon_ti"); - (*lang_hooks.types.register_builtin_type) (intEI_type_node, - "__builtin_neon_ei"); - (*lang_hooks.types.register_builtin_type) (intOI_type_node, - "__builtin_neon_oi"); - (*lang_hooks.types.register_builtin_type) (intCI_type_node, - "__builtin_neon_ci"); - (*lang_hooks.types.register_builtin_type) (intXI_type_node, - "__builtin_neon_xi"); +/* Set up all the iWMMXt builtins. This is + not called if TARGET_IWMMXT is zero. */ - /* Pointers to vector types. */ - V8QI_pointer_node = build_pointer_type (V8QI_type_node); - V4HI_pointer_node = build_pointer_type (V4HI_type_node); - V2SI_pointer_node = build_pointer_type (V2SI_type_node); - V2SF_pointer_node = build_pointer_type (V2SF_type_node); - V16QI_pointer_node = build_pointer_type (V16QI_type_node); - V8HI_pointer_node = build_pointer_type (V8HI_type_node); - V4SI_pointer_node = build_pointer_type (V4SI_type_node); - V4SF_pointer_node = build_pointer_type (V4SF_type_node); - V2DI_pointer_node = build_pointer_type (V2DI_type_node); +static void +arm_init_iwmmxt_builtins (void) +{ + const struct builtin_description * d; + size_t i; + tree endlink = void_list_node; - /* Operations which return results as pairs. */ - void_ftype_pv8qi_v8qi_v8qi = - build_function_type_list (void_type_node, V8QI_pointer_node, V8QI_type_node, - V8QI_type_node, NULL); - void_ftype_pv4hi_v4hi_v4hi = - build_function_type_list (void_type_node, V4HI_pointer_node, V4HI_type_node, - V4HI_type_node, NULL); - void_ftype_pv2si_v2si_v2si = - build_function_type_list (void_type_node, V2SI_pointer_node, V2SI_type_node, - V2SI_type_node, NULL); - void_ftype_pv2sf_v2sf_v2sf = - build_function_type_list (void_type_node, V2SF_pointer_node, V2SF_type_node, - V2SF_type_node, NULL); - void_ftype_pdi_di_di = - build_function_type_list (void_type_node, intDI_pointer_node, - neon_intDI_type_node, neon_intDI_type_node, NULL); - void_ftype_pv16qi_v16qi_v16qi = - build_function_type_list (void_type_node, V16QI_pointer_node, - V16QI_type_node, V16QI_type_node, NULL); - void_ftype_pv8hi_v8hi_v8hi = - build_function_type_list (void_type_node, V8HI_pointer_node, V8HI_type_node, - V8HI_type_node, NULL); - void_ftype_pv4si_v4si_v4si = - build_function_type_list (void_type_node, V4SI_pointer_node, V4SI_type_node, - V4SI_type_node, NULL); - void_ftype_pv4sf_v4sf_v4sf = - build_function_type_list (void_type_node, V4SF_pointer_node, V4SF_type_node, - V4SF_type_node, NULL); - void_ftype_pv2di_v2di_v2di = - build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node, - V2DI_type_node, NULL); + 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)); - dreg_types[0] = V8QI_type_node; - dreg_types[1] = V4HI_type_node; - dreg_types[2] = V2SI_type_node; - dreg_types[3] = V2SF_type_node; - dreg_types[4] = neon_intDI_type_node; + 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)))); - 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; + 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))); - 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); - } - } + /* 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))); - for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++) + /* 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++) { - neon_builtin_datum *d = &neon_builtin_data[i]; - - const char* const modenames[] = { - "v8qi", "v4hi", "v2si", "v2sf", "di", - "v16qi", "v8hi", "v4si", "v4sf", "v2di" - }; - char namebuf[60]; - tree ftype = NULL; - int is_load = 0, is_store = 0; - - 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_operands - 1; k >= 0; k--) - { - tree eltype; + /* Use one of the operands; the target can have a different mode for + mask-generating compares. */ + enum machine_mode mode; + tree type; - if (is_load && k == 1) - { - /* Neon load patterns always have the memory operand - (a SImode pointer) in the operand 1 position. We - want a const pointer to the element type in that - position. */ - gcc_assert (insn_data[d->code].operand[k].mode == SImode); + if (d->name == 0) + continue; - switch (d->mode) - { - case T_V8QI: - case T_V16QI: - eltype = const_intQI_pointer_node; - break; + mode = insn_data[d->icode].operand[1].mode; - case T_V4HI: - case T_V8HI: - eltype = const_intHI_pointer_node; - break; + 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; - case T_V2SI: - case T_V4SI: - eltype = const_intSI_pointer_node; - break; + default: + gcc_unreachable (); + } - case T_V2SF: - case T_V4SF: - eltype = const_float_pointer_node; - break; + def_mbuiltin (d->mask, d->name, type, d->code); + } - case T_DI: - case T_V2DI: - eltype = const_intDI_pointer_node; - break; + /* 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); - default: gcc_unreachable (); - } - } - else if (is_store && k == 0) - { - /* Similarly, Neon store patterns use operand 0 as - the memory location to store to (a SImode pointer). - Use a pointer to the element type of the store in - that position. */ - gcc_assert (insn_data[d->code].operand[k].mode == SImode); + 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); - switch (d->mode) - { - case T_V8QI: - case T_V16QI: - eltype = intQI_pointer_node; - break; + 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); - case T_V4HI: - case T_V8HI: - eltype = intHI_pointer_node; - break; + 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); - case T_V2SI: - case T_V4SI: - eltype = intSI_pointer_node; - break; + 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); - case T_V2SF: - case T_V4SF: - eltype = float_pointer_node; - break; + def_mbuiltin (FL_IWMMXT, "__builtin_arm_wshufh", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSHUFH); - case T_DI: - case T_V2DI: - eltype = intDI_pointer_node; - break; + 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); - 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 (); - } - } + 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); - if (k == 0 && !is_store) - return_type = eltype; - else - args = tree_cons (NULL_TREE, eltype, args); - } + 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); - ftype = build_function_type (return_type, args); - } - break; + 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); - 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; + 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); - 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; + 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); - default: - gcc_unreachable (); - } + 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); - gcc_assert (ftype != NULL); + 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); +} - sprintf (namebuf, "__builtin_neon_%s%s", d->name, modenames[d->mode]); +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; } static void diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 9951553..e172184 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2322,178 +2322,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