diff -ruN gcc/config/arm/arm-arches.def gcc/config/arm/arm-arches.def --- gcc/config/arm/arm-arches.def 2011-09-19 19:05:24.000000000 -0700 +++ gcc/config/arm/arm-arches.def 2013-01-27 20:14:06.000979281 -0800 @@ -1,6 +1,6 @@ /* ARM CPU architectures. Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -57,4 +57,4 @@ ARM_ARCH("armv7e-m", cortexm4, 7EM, FL_CO_PROC | FL_FOR_ARCH7EM) ARM_ARCH("ep9312", ep9312, 4T, FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4) ARM_ARCH("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT) -ARM_ARCH("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT) +ARM_ARCH("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2) diff -ruN gcc/config/arm/arm.c gcc/config/arm/arm.c --- gcc/config/arm/arm.c 2012-09-07 02:31:54.000000000 -0700 +++ gcc/config/arm/arm.c 2013-01-27 20:14:06.005979281 -0800 @@ -685,6 +685,7 @@ #define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */ #define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */ +#define FL_IWMMXT2 (1 << 30) /* "Intel Wireless MMX2 technology". */ /* Flags that only effect tuning, not available instructions. */ #define FL_TUNE (FL_WBUF | FL_VFPV2 | FL_STRONG | FL_LDSCHED \ @@ -766,6 +767,9 @@ /* Nonzero if this chip supports Intel Wireless MMX technology. */ int arm_arch_iwmmxt = 0; +/* Nonzero if this chip supports Intel Wireless MMX2 technology. */ +int arm_arch_iwmmxt2 = 0; + /* Nonzero if this chip is an XScale. */ int arm_arch_xscale = 0; @@ -1717,6 +1721,7 @@ arm_tune_wbuf = (tune_flags & FL_WBUF) != 0; arm_tune_xscale = (tune_flags & FL_XSCALE) != 0; arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0; + arm_arch_iwmmxt2 = (insn_flags & FL_IWMMXT2) != 0; arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0; arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0; arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0; @@ -1817,14 +1822,17 @@ } /* FPA and iWMMXt are incompatible because the insn encodings overlap. - VFP and iWMMXt can theoretically coexist, but it's unlikely such silicon - will ever exist. GCC makes no attempt to support this combination. */ - if (TARGET_IWMMXT && !TARGET_SOFT_FLOAT) - sorry ("iWMMXt and hardware floating point"); - - /* ??? iWMMXt insn patterns need auditing for Thumb-2. */ - if (TARGET_THUMB2 && TARGET_IWMMXT) - sorry ("Thumb-2 iWMMXt"); + VFP and iWMMXt however can coexist. */ + if (TARGET_IWMMXT && TARGET_HARD_FLOAT && !TARGET_VFP) + error ("iWMMXt and non-VFP floating point unit are incompatible"); + + /* iWMMXt and NEON are incompatible. */ + if (TARGET_IWMMXT && TARGET_NEON) + error ("iWMMXt and NEON are incompatible"); + + /* iWMMXt unsupported under Thumb mode. */ + if (TARGET_THUMB && TARGET_IWMMXT) + error ("iWMMXt unsupported under Thumb mode"); /* __fp16 support currently assumes the core has ldrh. */ if (!arm_arch4 && arm_fp16_format != ARM_FP16_FORMAT_NONE) @@ -19269,8 +19277,15 @@ FIXME? */ enum arm_builtins { - ARM_BUILTIN_GETWCX, - ARM_BUILTIN_SETWCX, + ARM_BUILTIN_GETWCGR0, + ARM_BUILTIN_GETWCGR1, + ARM_BUILTIN_GETWCGR2, + ARM_BUILTIN_GETWCGR3, + + ARM_BUILTIN_SETWCGR0, + ARM_BUILTIN_SETWCGR1, + ARM_BUILTIN_SETWCGR2, + ARM_BUILTIN_SETWCGR3, ARM_BUILTIN_WZERO, @@ -19293,7 +19308,11 @@ ARM_BUILTIN_WSADH, ARM_BUILTIN_WSADHZ, - ARM_BUILTIN_WALIGN, + ARM_BUILTIN_WALIGNI, + ARM_BUILTIN_WALIGNR0, + ARM_BUILTIN_WALIGNR1, + ARM_BUILTIN_WALIGNR2, + ARM_BUILTIN_WALIGNR3, ARM_BUILTIN_TMIA, ARM_BUILTIN_TMIAPH, @@ -19429,6 +19448,81 @@ ARM_BUILTIN_WUNPCKELUH, ARM_BUILTIN_WUNPCKELUW, + ARM_BUILTIN_WABSB, + ARM_BUILTIN_WABSH, + ARM_BUILTIN_WABSW, + + ARM_BUILTIN_WADDSUBHX, + ARM_BUILTIN_WSUBADDHX, + + ARM_BUILTIN_WABSDIFFB, + ARM_BUILTIN_WABSDIFFH, + ARM_BUILTIN_WABSDIFFW, + + ARM_BUILTIN_WADDCH, + ARM_BUILTIN_WADDCW, + + ARM_BUILTIN_WAVG4, + ARM_BUILTIN_WAVG4R, + + ARM_BUILTIN_WMADDSX, + ARM_BUILTIN_WMADDUX, + + ARM_BUILTIN_WMADDSN, + ARM_BUILTIN_WMADDUN, + + ARM_BUILTIN_WMULWSM, + ARM_BUILTIN_WMULWUM, + + ARM_BUILTIN_WMULWSMR, + ARM_BUILTIN_WMULWUMR, + + ARM_BUILTIN_WMULWL, + + ARM_BUILTIN_WMULSMR, + ARM_BUILTIN_WMULUMR, + + ARM_BUILTIN_WQMULM, + ARM_BUILTIN_WQMULMR, + + ARM_BUILTIN_WQMULWM, + ARM_BUILTIN_WQMULWMR, + + ARM_BUILTIN_WADDBHUSM, + ARM_BUILTIN_WADDBHUSL, + + ARM_BUILTIN_WQMIABB, + ARM_BUILTIN_WQMIABT, + ARM_BUILTIN_WQMIATB, + ARM_BUILTIN_WQMIATT, + + ARM_BUILTIN_WQMIABBN, + ARM_BUILTIN_WQMIABTN, + ARM_BUILTIN_WQMIATBN, + ARM_BUILTIN_WQMIATTN, + + ARM_BUILTIN_WMIABB, + ARM_BUILTIN_WMIABT, + ARM_BUILTIN_WMIATB, + ARM_BUILTIN_WMIATT, + + ARM_BUILTIN_WMIABBN, + ARM_BUILTIN_WMIABTN, + ARM_BUILTIN_WMIATBN, + ARM_BUILTIN_WMIATTN, + + ARM_BUILTIN_WMIAWBB, + ARM_BUILTIN_WMIAWBT, + ARM_BUILTIN_WMIAWTB, + ARM_BUILTIN_WMIAWTT, + + ARM_BUILTIN_WMIAWBBN, + ARM_BUILTIN_WMIAWBTN, + ARM_BUILTIN_WMIAWTBN, + ARM_BUILTIN_WMIAWTTN, + + ARM_BUILTIN_WMERGE, + ARM_BUILTIN_THREAD_POINTER, ARM_BUILTIN_NEON_BASE, @@ -19961,6 +20055,10 @@ { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \ ARM_BUILTIN_##builtin, UNKNOWN, 0 }, +#define IWMMXT2_BUILTIN(code, string, builtin) \ + { FL_IWMMXT2, 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) @@ -20017,44 +20115,45 @@ 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) + IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX) + IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX) + IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB) + IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH) + IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW) + IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4) + IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R) + IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM) + IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM) + IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR) + IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR) + IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL) + IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR) + IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR) + IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM) + IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR) + IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM) + IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR) + IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0) + IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1) + IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2) + IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3) #define IWMMXT_BUILTIN2(code, builtin) \ { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 }, +#define IWMMXT2_BUILTIN2(code, builtin) \ + { FL_IWMMXT2, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 }, + + IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM) + IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL) 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) + IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ) + IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ) }; static const struct builtin_description bdesc_1arg[] = @@ -20077,6 +20176,12 @@ IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB) IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH) IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW) + IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB) + IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH) + IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW) + IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB) + IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH) + IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW) }; /* Set up all the iWMMXt builtins. This is not called if @@ -20092,9 +20197,6 @@ 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_list (integer_type_node, - integer_type_node, NULL_TREE); tree v8qi_ftype_v8qi_v8qi_int = build_function_type_list (V8QI_type_node, V8QI_type_node, V8QI_type_node, @@ -20156,6 +20258,9 @@ tree v4hi_ftype_v2si_v2si = build_function_type_list (V4HI_type_node, V2SI_type_node, V2SI_type_node, NULL_TREE); + tree v8qi_ftype_v4hi_v8qi + = build_function_type_list (V8QI_type_node, + V4HI_type_node, V8QI_type_node, NULL_TREE); tree v2si_ftype_v4hi_v4hi = build_function_type_list (V2SI_type_node, V4HI_type_node, V4HI_type_node, NULL_TREE); @@ -20170,12 +20275,10 @@ = build_function_type_list (V2SI_type_node, V2SI_type_node, long_long_integer_type_node, NULL_TREE); - tree void_ftype_int_int - = build_function_type_list (void_type_node, - integer_type_node, integer_type_node, - NULL_TREE); tree di_ftype_void = build_function_type_list (long_long_unsigned_type_node, NULL_TREE); + tree int_ftype_void + = build_function_type_list (integer_type_node, NULL_TREE); tree di_ftype_v8qi = build_function_type_list (long_long_integer_type_node, V8QI_type_node, NULL_TREE); @@ -20191,6 +20294,15 @@ tree v4hi_ftype_v8qi = build_function_type_list (V4HI_type_node, V8QI_type_node, NULL_TREE); + tree v8qi_ftype_v8qi + = build_function_type_list (V8QI_type_node, + V8QI_type_node, NULL_TREE); + tree v4hi_ftype_v4hi + = build_function_type_list (V4HI_type_node, + V4HI_type_node, NULL_TREE); + tree v2si_ftype_v2si + = build_function_type_list (V2SI_type_node, + V2SI_type_node, NULL_TREE); tree di_ftype_di_v4hi_v4hi = build_function_type_list (long_long_unsigned_type_node, @@ -20203,6 +20315,48 @@ V4HI_type_node,V4HI_type_node, NULL_TREE); + tree v2si_ftype_v2si_v4hi_v4hi + = build_function_type_list (V2SI_type_node, + V2SI_type_node, V4HI_type_node, + V4HI_type_node, NULL_TREE); + + tree v2si_ftype_v2si_v8qi_v8qi + = build_function_type_list (V2SI_type_node, + V2SI_type_node, V8QI_type_node, + V8QI_type_node, NULL_TREE); + + tree di_ftype_di_v2si_v2si + = build_function_type_list (long_long_unsigned_type_node, + long_long_unsigned_type_node, + V2SI_type_node, V2SI_type_node, + NULL_TREE); + + tree di_ftype_di_di_int + = build_function_type_list (long_long_unsigned_type_node, + long_long_unsigned_type_node, + long_long_unsigned_type_node, + integer_type_node, NULL_TREE); + + tree void_ftype_void + = build_function_type_list (void_type_node, + NULL_TREE); + + tree void_ftype_int + = build_function_type_list (void_type_node, + integer_type_node, NULL_TREE); + + tree v8qi_ftype_char + = build_function_type_list (V8QI_type_node, + signed_char_type_node, NULL_TREE); + + tree v4hi_ftype_short + = build_function_type_list (V4HI_type_node, + short_integer_type_node, NULL_TREE); + + tree v2si_ftype_int + = build_function_type_list (V2SI_type_node, + integer_type_node, NULL_TREE); + /* Normal vector binops. */ tree v8qi_ftype_v8qi_v8qi = build_function_type_list (V8QI_type_node, @@ -20260,9 +20414,19 @@ def_mbuiltin (FL_IWMMXT, "__builtin_arm_" NAME, (TYPE), \ ARM_BUILTIN_ ## CODE) +#define iwmmx2_mbuiltin(NAME, TYPE, CODE) \ + def_mbuiltin (FL_IWMMXT2, "__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 ("setwcgr0", void_ftype_int, SETWCGR0); + iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1); + iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2); + iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3); + iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0); + iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1); + iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2); + iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3); iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH); iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW); @@ -20294,8 +20458,14 @@ 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 ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB); + iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH); + iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS); + iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX); + iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN); + iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU); + iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX); + iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN); iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ); iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ); @@ -20317,6 +20487,9 @@ iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH); iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW); + iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM); + iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL); + iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS); iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS); iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS); @@ -20342,7 +20515,7 @@ 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 ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI); 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); @@ -20350,7 +20523,48 @@ iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB); iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT); + iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB); + iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH); + iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW); + + iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB); + iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT); + iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB); + iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT); + + iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN); + iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN); + iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN); + iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN); + + iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB); + iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT); + iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB); + iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT); + + iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN); + iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN); + iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN); + iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN); + + iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB); + iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT); + iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB); + iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT); + + iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN); + iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN); + iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN); + iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN); + + iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE); + + iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB); + iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH); + iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW); + #undef iwmmx_mbuiltin +#undef iwmmx2_mbuiltin } static void @@ -20507,7 +20721,8 @@ || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) target = gen_reg_rtx (tmode); - gcc_assert (GET_MODE (op0) == mode0 && GET_MODE (op1) == mode1); + gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode) + && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)); if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) op0 = copy_to_mode_reg (mode0, op0); @@ -21015,6 +21230,10 @@ enum machine_mode mode0; enum machine_mode mode1; enum machine_mode mode2; + int opint; + int selector; + int mask; + int imm; if (fcode >= ARM_BUILTIN_NEON_BASE) return arm_expand_neon_builtin (fcode, exp, target); @@ -21049,6 +21268,24 @@ error ("selector must be an immediate"); return gen_reg_rtx (tmode); } + + opint = INTVAL (op1); + if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB) + { + if (opint > 7 || opint < 0) + error ("the range of selector should be in 0 to 7"); + } + else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH) + { + if (opint > 3 || opint < 0) + error ("the range of selector should be in 0 to 3"); + } + else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */ + { + if (opint > 1 || opint < 0) + error ("the range of selector should be in 0 to 1"); + } + if (target == 0 || GET_MODE (target) != tmode || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) @@ -21059,11 +21296,61 @@ emit_insn (pat); return target; + case ARM_BUILTIN_WALIGNI: + /* If op2 is immediate, call walighi, else call walighr. */ + arg0 = CALL_EXPR_ARG (exp, 0); + arg1 = CALL_EXPR_ARG (exp, 1); + arg2 = CALL_EXPR_ARG (exp, 2); + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + op2 = expand_normal (arg2); + if (GET_CODE (op2) == CONST_INT) + { + icode = CODE_FOR_iwmmxt_waligni; + tmode = insn_data[icode].operand[0].mode; + mode0 = insn_data[icode].operand[1].mode; + mode1 = insn_data[icode].operand[2].mode; + mode2 = insn_data[icode].operand[3].mode; + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) + op1 = copy_to_mode_reg (mode1, op1); + gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2)); + selector = INTVAL (op2); + if (selector > 7 || selector < 0) + error ("the range of selector should be in 0 to 7"); + } + else + { + icode = CODE_FOR_iwmmxt_walignr; + tmode = insn_data[icode].operand[0].mode; + mode0 = insn_data[icode].operand[1].mode; + mode1 = insn_data[icode].operand[2].mode; + mode2 = insn_data[icode].operand[3].mode; + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) + op1 = copy_to_mode_reg (mode1, op1); + if (!(*insn_data[icode].operand[3].predicate) (op2, mode2)) + op2 = copy_to_mode_reg (mode2, op2); + } + if (target == 0 + || GET_MODE (target) != tmode + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) + target = gen_reg_rtx (tmode); + pat = GEN_FCN (icode) (target, op0, op1, op2); + if (!pat) + return 0; + emit_insn (pat); + return target; + case ARM_BUILTIN_TINSRB: case ARM_BUILTIN_TINSRH: case ARM_BUILTIN_TINSRW: + case ARM_BUILTIN_WMERGE: icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh + : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge : CODE_FOR_iwmmxt_tinsrw); arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); @@ -21082,10 +21369,30 @@ op1 = copy_to_mode_reg (mode1, op1); if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) { - /* @@@ better error message */ error ("selector must be an immediate"); return const0_rtx; } + if (icode == CODE_FOR_iwmmxt_wmerge) + { + selector = INTVAL (op2); + if (selector > 7 || selector < 0) + error ("the range of selector should be in 0 to 7"); + } + if ((icode == CODE_FOR_iwmmxt_tinsrb) + || (icode == CODE_FOR_iwmmxt_tinsrh) + || (icode == CODE_FOR_iwmmxt_tinsrw)) + { + mask = 0x01; + selector= INTVAL (op2); + if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7)) + error ("the range of selector should be in 0 to 7"); + else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3)) + error ("the range of selector should be in 0 to 3"); + else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1)) + error ("the range of selector should be in 0 to 1"); + mask <<= selector; + op2 = gen_rtx_CONST_INT (SImode, mask); + } if (target == 0 || GET_MODE (target) != tmode || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) @@ -21096,19 +21403,42 @@ emit_insn (pat); return target; - case ARM_BUILTIN_SETWCX: + case ARM_BUILTIN_SETWCGR0: + case ARM_BUILTIN_SETWCGR1: + case ARM_BUILTIN_SETWCGR2: + case ARM_BUILTIN_SETWCGR3: + icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0 + : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1 + : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2 + : CODE_FOR_iwmmxt_setwcgr3); arg0 = CALL_EXPR_ARG (exp, 0); - arg1 = CALL_EXPR_ARG (exp, 1); - op0 = force_reg (SImode, expand_normal (arg0)); - op1 = expand_normal (arg1); - emit_insn (gen_iwmmxt_tmcr (op1, op0)); + op0 = expand_normal (arg0); + mode0 = insn_data[icode].operand[0].mode; + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + pat = GEN_FCN (icode) (op0); + if (!pat) + return 0; + emit_insn (pat); return 0; - case ARM_BUILTIN_GETWCX: - arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); - target = gen_reg_rtx (SImode); - emit_insn (gen_iwmmxt_tmrc (target, op0)); + case ARM_BUILTIN_GETWCGR0: + case ARM_BUILTIN_GETWCGR1: + case ARM_BUILTIN_GETWCGR2: + case ARM_BUILTIN_GETWCGR3: + icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0 + : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1 + : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2 + : CODE_FOR_iwmmxt_getwcgr3); + tmode = insn_data[icode].operand[0].mode; + if (target == 0 + || GET_MODE (target) != tmode + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) + target = gen_reg_rtx (tmode); + pat = GEN_FCN (icode) (target); + if (!pat) + return 0; + emit_insn (pat); return target; case ARM_BUILTIN_WSHUFH: @@ -21125,10 +21455,12 @@ op0 = copy_to_mode_reg (mode1, op0); if (! (*insn_data[icode].operand[2].predicate) (op1, mode2)) { - /* @@@ better error message */ error ("mask must be an immediate"); return const0_rtx; } + selector = INTVAL (op1); + if (selector < 0 || selector > 255) + error ("the range of mask should be in 0 to 255"); if (target == 0 || GET_MODE (target) != tmode || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) @@ -21139,10 +21471,18 @@ emit_insn (pat); return target; - case ARM_BUILTIN_WSADB: - return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, exp, target); - case ARM_BUILTIN_WSADH: - return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, exp, target); + case ARM_BUILTIN_WMADDS: + return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target); + case ARM_BUILTIN_WMADDSX: + return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target); + case ARM_BUILTIN_WMADDSN: + return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target); + case ARM_BUILTIN_WMADDU: + return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target); + case ARM_BUILTIN_WMADDUX: + return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target); + case ARM_BUILTIN_WMADDUN: + return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target); case ARM_BUILTIN_WSADBZ: return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target); case ARM_BUILTIN_WSADHZ: @@ -21151,13 +21491,38 @@ /* Several three-argument builtins. */ case ARM_BUILTIN_WMACS: case ARM_BUILTIN_WMACU: - case ARM_BUILTIN_WALIGN: case ARM_BUILTIN_TMIA: case ARM_BUILTIN_TMIAPH: case ARM_BUILTIN_TMIATT: case ARM_BUILTIN_TMIATB: case ARM_BUILTIN_TMIABT: case ARM_BUILTIN_TMIABB: + case ARM_BUILTIN_WQMIABB: + case ARM_BUILTIN_WQMIABT: + case ARM_BUILTIN_WQMIATB: + case ARM_BUILTIN_WQMIATT: + case ARM_BUILTIN_WQMIABBN: + case ARM_BUILTIN_WQMIABTN: + case ARM_BUILTIN_WQMIATBN: + case ARM_BUILTIN_WQMIATTN: + case ARM_BUILTIN_WMIABB: + case ARM_BUILTIN_WMIABT: + case ARM_BUILTIN_WMIATB: + case ARM_BUILTIN_WMIATT: + case ARM_BUILTIN_WMIABBN: + case ARM_BUILTIN_WMIABTN: + case ARM_BUILTIN_WMIATBN: + case ARM_BUILTIN_WMIATTN: + case ARM_BUILTIN_WMIAWBB: + case ARM_BUILTIN_WMIAWBT: + case ARM_BUILTIN_WMIAWTB: + case ARM_BUILTIN_WMIAWTT: + case ARM_BUILTIN_WMIAWBBN: + case ARM_BUILTIN_WMIAWBTN: + case ARM_BUILTIN_WMIAWTBN: + case ARM_BUILTIN_WMIAWTTN: + case ARM_BUILTIN_WSADB: + case ARM_BUILTIN_WSADH: icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia @@ -21166,7 +21531,32 @@ : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt - : CODE_FOR_iwmmxt_walign); + : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb + : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt + : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb + : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt + : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn + : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn + : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn + : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn + : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb + : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt + : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb + : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt + : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn + : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn + : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn + : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn + : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb + : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt + : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb + : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt + : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn + : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn + : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn + : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn + : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb + : CODE_FOR_iwmmxt_wsadh); arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); arg2 = CALL_EXPR_ARG (exp, 2); @@ -21199,6 +21589,123 @@ emit_insn (gen_iwmmxt_clrdi (target)); return target; + case ARM_BUILTIN_WSRLHI: + case ARM_BUILTIN_WSRLWI: + case ARM_BUILTIN_WSRLDI: + case ARM_BUILTIN_WSLLHI: + case ARM_BUILTIN_WSLLWI: + case ARM_BUILTIN_WSLLDI: + case ARM_BUILTIN_WSRAHI: + case ARM_BUILTIN_WSRAWI: + case ARM_BUILTIN_WSRADI: + case ARM_BUILTIN_WRORHI: + case ARM_BUILTIN_WRORWI: + case ARM_BUILTIN_WRORDI: + case ARM_BUILTIN_WSRLH: + case ARM_BUILTIN_WSRLW: + case ARM_BUILTIN_WSRLD: + case ARM_BUILTIN_WSLLH: + case ARM_BUILTIN_WSLLW: + case ARM_BUILTIN_WSLLD: + case ARM_BUILTIN_WSRAH: + case ARM_BUILTIN_WSRAW: + case ARM_BUILTIN_WSRAD: + case ARM_BUILTIN_WRORH: + case ARM_BUILTIN_WRORW: + case ARM_BUILTIN_WRORD: + icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt + : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt + : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt + : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt + : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt + : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt + : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt + : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt + : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt + : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3 + : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3 + : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3 + : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di + : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di + : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di + : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di + : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di + : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di + : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di + : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di + : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di + : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di + : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di + : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di + : CODE_FOR_nothing); + arg1 = CALL_EXPR_ARG (exp, 1); + op1 = expand_normal (arg1); + if (GET_MODE (op1) == VOIDmode) + { + imm = INTVAL (op1); + if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI + || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW) + && (imm < 0 || imm > 32)) + { + if (fcode == ARM_BUILTIN_WRORHI) + error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code."); + else if (fcode == ARM_BUILTIN_WRORWI) + error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code."); + else if (fcode == ARM_BUILTIN_WRORH) + error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code."); + else + error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code."); + } + else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD) + && (imm < 0 || imm > 64)) + { + if (fcode == ARM_BUILTIN_WRORDI) + error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code."); + else + error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code."); + } + else if (imm < 0) + { + if (fcode == ARM_BUILTIN_WSRLHI) + error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code."); + else if (fcode == ARM_BUILTIN_WSRLWI) + error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code."); + else if (fcode == ARM_BUILTIN_WSRLDI) + error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code."); + else if (fcode == ARM_BUILTIN_WSLLHI) + error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code."); + else if (fcode == ARM_BUILTIN_WSLLWI) + error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code."); + else if (fcode == ARM_BUILTIN_WSLLDI) + error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code."); + else if (fcode == ARM_BUILTIN_WSRAHI) + error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code."); + else if (fcode == ARM_BUILTIN_WSRAWI) + error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code."); + else if (fcode == ARM_BUILTIN_WSRADI) + error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code."); + else if (fcode == ARM_BUILTIN_WSRLH) + error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code."); + else if (fcode == ARM_BUILTIN_WSRLW) + error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code."); + else if (fcode == ARM_BUILTIN_WSRLD) + error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code."); + else if (fcode == ARM_BUILTIN_WSLLH) + error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code."); + else if (fcode == ARM_BUILTIN_WSLLW) + error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code."); + else if (fcode == ARM_BUILTIN_WSLLD) + error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code."); + else if (fcode == ARM_BUILTIN_WSRAH) + error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code."); + else if (fcode == ARM_BUILTIN_WSRAW) + error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code."); + else + error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code."); + } + } + return arm_expand_binop_builtin (icode, exp, target); + case ARM_BUILTIN_THREAD_POINTER: return arm_load_tp (target); @@ -24287,6 +24794,95 @@ return ""; } +/* Output assembly for a WMMX immediate shift instruction. */ +const char * +arm_output_iwmmxt_shift_immediate (const char *insn_name, rtx *operands, bool wror_or_wsra) +{ + int shift = INTVAL (operands[2]); + char templ[50]; + enum machine_mode opmode = GET_MODE (operands[0]); + + gcc_assert (shift >= 0); + + /* If the shift value in the register versions is > 63 (for D qualifier), + 31 (for W qualifier) or 15 (for H qualifier). */ + if (((opmode == V4HImode) && (shift > 15)) + || ((opmode == V2SImode) && (shift > 31)) + || ((opmode == DImode) && (shift > 63))) + { + if (wror_or_wsra) + { + sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, 32); + output_asm_insn (templ, operands); + if (opmode == DImode) + { + sprintf (templ, "%s\t%%0, %%0, #%d", insn_name, 32); + output_asm_insn (templ, operands); + } + } + else + { + /* The destination register will contain all zeros. */ + sprintf (templ, "wzero\t%%0"); + output_asm_insn (templ, operands); + } + return ""; + } + + if ((opmode == DImode) && (shift > 32)) + { + sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, 32); + output_asm_insn (templ, operands); + sprintf (templ, "%s\t%%0, %%0, #%d", insn_name, shift - 32); + output_asm_insn (templ, operands); + } + else + { + sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, shift); + output_asm_insn (templ, operands); + } + return ""; +} + +/* Output assembly for a WMMX tinsr instruction. */ +const char * +arm_output_iwmmxt_tinsr (rtx *operands) +{ + int mask = INTVAL (operands[3]); + int i; + char templ[50]; + int units = mode_nunits[GET_MODE (operands[0])]; + gcc_assert ((mask & (mask - 1)) == 0); + for (i = 0; i < units; ++i) + { + if ((mask & 0x01) == 1) + { + break; + } + mask >>= 1; + } + gcc_assert (i < units); + { + switch (GET_MODE (operands[0])) + { + case V8QImode: + sprintf (templ, "tinsrb%%?\t%%0, %%2, #%d", i); + break; + case V4HImode: + sprintf (templ, "tinsrh%%?\t%%0, %%2, #%d", i); + break; + case V2SImode: + sprintf (templ, "tinsrw%%?\t%%0, %%2, #%d", i); + break; + default: + gcc_unreachable (); + break; + } + output_asm_insn (templ, operands); + } + return ""; +} + /* Output a Thumb-1 casesi dispatch sequence. */ const char * thumb1_output_casesi (rtx *operands) diff -ruN gcc/config/arm/arm-cores.def gcc/config/arm/arm-cores.def --- gcc/config/arm/arm-cores.def 2012-02-27 03:26:49.000000000 -0800 +++ gcc/config/arm/arm-cores.def 2013-01-27 20:14:06.000979281 -0800 @@ -1,5 +1,5 @@ /* ARM CPU Cores - Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Free Software Foundation, Inc. Written by CodeSourcery, LLC @@ -105,7 +105,7 @@ ARM_CORE("arm1022e", arm1022e, 5TE, FL_LDSCHED, fastmul) ARM_CORE("xscale", xscale, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale) ARM_CORE("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale) -ARM_CORE("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale) +ARM_CORE("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2, xscale) ARM_CORE("fa606te", fa606te, 5TE, FL_LDSCHED, 9e) ARM_CORE("fa626te", fa626te, 5TE, FL_LDSCHED, 9e) ARM_CORE("fmp626", fmp626, 5TE, FL_LDSCHED, 9e) diff -ruN gcc/config/arm/arm.h gcc/config/arm/arm.h --- gcc/config/arm/arm.h 2012-01-09 20:14:09.000000000 -0800 +++ gcc/config/arm/arm.h 2013-01-27 20:14:06.006979280 -0800 @@ -97,6 +97,8 @@ builtin_define ("__XSCALE__"); \ if (arm_arch_iwmmxt) \ builtin_define ("__IWMMXT__"); \ + if (arm_arch_iwmmxt2) \ + builtin_define ("__IWMMXT2__"); \ if (TARGET_AAPCS_BASED) \ { \ if (arm_pcs_default == ARM_PCS_AAPCS_VFP) \ @@ -194,7 +196,9 @@ #define TARGET_MAVERICK (arm_fpu_desc->model == ARM_FP_MODEL_MAVERICK) #define TARGET_VFP (arm_fpu_desc->model == ARM_FP_MODEL_VFP) #define TARGET_IWMMXT (arm_arch_iwmmxt) +#define TARGET_IWMMXT2 (arm_arch_iwmmxt2) #define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_32BIT) +#define TARGET_REALLY_IWMMXT2 (TARGET_IWMMXT2 && TARGET_32BIT) #define TARGET_IWMMXT_ABI (TARGET_32BIT && arm_abi == ARM_ABI_IWMMXT) #define TARGET_ARM (! TARGET_THUMB) #define TARGET_EITHER 1 /* (TARGET_ARM | TARGET_THUMB) */ @@ -410,6 +414,9 @@ /* Nonzero if this chip supports Intel XScale with Wireless MMX technology. */ extern int arm_arch_iwmmxt; +/* Nonzero if this chip supports Intel Wireless MMX2 technology. */ +extern int arm_arch_iwmmxt2; + /* Nonzero if this chip is an XScale. */ extern int arm_arch_xscale; diff -ruN gcc/config/arm/arm.md gcc/config/arm/arm.md --- gcc/config/arm/arm.md 2012-08-06 07:34:27.000000000 -0700 +++ gcc/config/arm/arm.md 2013-01-27 20:18:18.429963416 -0800 @@ -62,6 +62,7 @@ ;; UNSPEC Usage: ;; Note: sin and cos are no-longer used. ;; Unspec enumerators for Neon are defined in neon.md. +;; Unspec enumerators for iwmmxt2 are defined in iwmmxt2.md (define_c_enum "unspec" [ UNSPEC_SIN ; `sin' operation (MODE_FLOAT): @@ -98,8 +99,7 @@ UNSPEC_WMACSZ ; Used by the intrinsic form of the iWMMXt WMACSZ instruction. UNSPEC_WMACUZ ; Used by the intrinsic form of the iWMMXt WMACUZ instruction. UNSPEC_CLRDI ; Used by the intrinsic form of the iWMMXt CLRDI instruction. - UNSPEC_WMADDS ; Used by the intrinsic form of the iWMMXt WMADDS instruction. - UNSPEC_WMADDU ; Used by the intrinsic form of the iWMMXt WMADDU instruction. + UNSPEC_WALIGNI ; Used by the intrinsic form of the iWMMXt WALIGN instruction. UNSPEC_TLS ; A symbol that has been treated properly for TLS usage. UNSPEC_PIC_LABEL ; A label used for PIC access that does not appear in the ; instruction stream. @@ -196,7 +196,7 @@ ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without ; arm_arch6. This attribute is used to compute attribute "enabled", ; use type "any" to enable an alternative in all cases. -(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,onlya8,nota8" +(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,onlya8,nota8,iwmmxt,iwmmxt2" (const_string "any")) (define_attr "arch_enabled" "no,yes" @@ -237,6 +237,10 @@ (and (eq_attr "arch" "nota8") (not (eq_attr "tune" "cortexa8"))) + (const_string "yes") + + (and (eq_attr "arch" "iwmmxt2") + (match_test "TARGET_REALLY_IWMMXT2")) (const_string "yes")] (const_string "no"))) @@ -351,6 +355,10 @@ (const_string "yes") (const_string "no"))) +; wtype for WMMX insn scheduling purposes. +(define_attr "wtype" + "none,wor,wxor,wand,wandn,wmov,tmcrr,tmrrc,wldr,wstr,tmcr,tmrc,wadd,wsub,wmul,wmac,wavg2,tinsr,textrm,wshufh,wcmpeq,wcmpgt,wmax,wmin,wpack,wunpckih,wunpckil,wunpckeh,wunpckel,wror,wsra,wsrl,wsll,wmadd,tmia,tmiaph,tmiaxy,tbcst,tmovmsk,wacc,waligni,walignr,tandc,textrc,torc,torvsc,wsad,wabs,wabsdiff,waddsubhx,wsubaddhx,wavg4,wmulw,wqmulm,wqmulwm,waddbhus,wqmiaxy,wmiaxy,wmiawxy,wmerge" (const_string "none")) + ; Load scheduling, set from the arm_ld_sched variable ; initialized by arm_option_override() (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) @@ -527,6 +535,7 @@ (const_string "yes") (const_string "no")))) +(include "marvell-f-iwmmxt.md") (include "arm-generic.md") (include "arm926ejs.md") (include "arm1020e.md") diff -ruN gcc/config/arm/arm-protos.h gcc/config/arm/arm-protos.h --- gcc/config/arm/arm-protos.h 2012-01-09 20:47:26.000000000 -0800 +++ gcc/config/arm/arm-protos.h 2013-01-27 20:14:06.000979281 -0800 @@ -156,6 +156,8 @@ extern void arm_set_return_address (rtx, rtx); extern int arm_eliminable_register (rtx); extern const char *arm_output_shift(rtx *, int); +extern const char *arm_output_iwmmxt_shift_immediate (const char *, rtx *, bool); +extern const char *arm_output_iwmmxt_tinsr (rtx *); extern unsigned int arm_sync_loop_insns (rtx , rtx *); extern int arm_attr_length_push_multi(rtx, rtx); extern void arm_expand_compare_and_swap (rtx op[]); diff -ruN gcc/config/arm/iterators.md gcc/config/arm/iterators.md --- gcc/config/arm/iterators.md 2011-12-23 05:53:17.000000000 -0800 +++ gcc/config/arm/iterators.md 2013-01-27 20:14:06.008979280 -0800 @@ -1,5 +1,5 @@ ;; Code and mode itertator and attribute definitions for the ARM backend -;; Copyright (C) 2010 Free Software Foundation, Inc. +;; Copyright (C) 2010, 2012 Free Software Foundation, Inc. ;; Contributed by ARM Ltd. ;; ;; This file is part of GCC. @@ -45,6 +45,8 @@ ;; Integer element sizes implemented by IWMMXT. (define_mode_iterator VMMX [V2SI V4HI V8QI]) +(define_mode_iterator VMMX2 [V4HI V2SI]) + ;; Integer element sizes for shifts. (define_mode_iterator VSHFT [V4HI V2SI DI]) diff -ruN gcc/config/arm/iwmmxt2.md gcc/config/arm/iwmmxt2.md --- gcc/config/arm/iwmmxt2.md 1969-12-31 16:00:00.000000000 -0800 +++ gcc/config/arm/iwmmxt2.md 2013-01-27 20:14:06.009979280 -0800 @@ -0,0 +1,918 @@ +;; Patterns for the Intel Wireless MMX technology architecture. +;; Copyright (C) 2011, 2012 Free Software Foundation, Inc. +;; Written by Marvell, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_c_enum "unspec" [ + UNSPEC_WADDC ; Used by the intrinsic form of the iWMMXt WADDC instruction. + UNSPEC_WABS ; Used by the intrinsic form of the iWMMXt WABS instruction. + UNSPEC_WQMULWMR ; Used by the intrinsic form of the iWMMXt WQMULWMR instruction. + UNSPEC_WQMULMR ; Used by the intrinsic form of the iWMMXt WQMULMR instruction. + UNSPEC_WQMULWM ; Used by the intrinsic form of the iWMMXt WQMULWM instruction. + UNSPEC_WQMULM ; Used by the intrinsic form of the iWMMXt WQMULM instruction. + UNSPEC_WQMIAxyn ; Used by the intrinsic form of the iWMMXt WMIAxyn instruction. + UNSPEC_WQMIAxy ; Used by the intrinsic form of the iWMMXt WMIAxy instruction. + UNSPEC_TANDC ; Used by the intrinsic form of the iWMMXt TANDC instruction. + UNSPEC_TORC ; Used by the intrinsic form of the iWMMXt TORC instruction. + UNSPEC_TORVSC ; Used by the intrinsic form of the iWMMXt TORVSC instruction. + UNSPEC_TEXTRC ; Used by the intrinsic form of the iWMMXt TEXTRC instruction. +]) + +(define_insn "iwmmxt_wabs3" + [(set (match_operand:VMMX 0 "register_operand" "=y") + (unspec:VMMX [(match_operand:VMMX 1 "register_operand" "y")] UNSPEC_WABS))] + "TARGET_REALLY_IWMMXT" + "wabs%?\\t%0, %1" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wabs")] +) + +(define_insn "iwmmxt_wabsdiffb" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (truncate:V8QI + (abs:V8HI + (minus:V8HI + (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y"))))))] + "TARGET_REALLY_IWMMXT" + "wabsdiffb%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wabsdiff")] +) + +(define_insn "iwmmxt_wabsdiffh" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate: V4HI + (abs:V4SI + (minus:V4SI + (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))))))] + "TARGET_REALLY_IWMMXT" + "wabsdiffh%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wabsdiff")] +) + +(define_insn "iwmmxt_wabsdiffw" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (truncate: V2SI + (abs:V2DI + (minus:V2DI + (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (zero_extend:V2DI (match_operand:V2SI 2 "register_operand" "y"))))))] + "TARGET_REALLY_IWMMXT" + "wabsdiffw%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wabsdiff")] +) + +(define_insn "iwmmxt_waddsubhx" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_merge:V4HI + (ss_minus:V4HI + (match_operand:V4HI 1 "register_operand" "y") + (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)]))) + (ss_plus:V4HI + (match_dup 1) + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)]))) + (const_int 10)))] + "TARGET_REALLY_IWMMXT" + "waddsubhx%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "waddsubhx")] +) + +(define_insn "iwmmxt_wsubaddhx" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_merge:V4HI + (ss_plus:V4HI + (match_operand:V4HI 1 "register_operand" "y") + (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)]))) + (ss_minus:V4HI + (match_dup 1) + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)]))) + (const_int 10)))] + "TARGET_REALLY_IWMMXT" + "wsubaddhx%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsubaddhx")] +) + +(define_insn "addc3" + [(set (match_operand:VMMX2 0 "register_operand" "=y") + (unspec:VMMX2 + [(plus:VMMX2 + (match_operand:VMMX2 1 "register_operand" "y") + (match_operand:VMMX2 2 "register_operand" "y"))] UNSPEC_WADDC))] + "TARGET_REALLY_IWMMXT" + "waddc%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) + +(define_insn "iwmmxt_avg4" +[(set (match_operand:V8QI 0 "register_operand" "=y") + (truncate:V8QI + (vec_select:V8HI + (vec_merge:V8HI + (lshiftrt:V8HI + (plus:V8HI + (plus:V8HI + (plus:V8HI + (plus:V8HI + (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y"))) + (vec_select:V8HI (zero_extend:V8HI (match_dup 1)) + (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2) + (const_int 3) (const_int 4) (const_int 5) (const_int 6)]))) + (vec_select:V8HI (zero_extend:V8HI (match_dup 2)) + (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2) + (const_int 3) (const_int 4) (const_int 5) (const_int 6)]))) + (const_vector:V8HI [(const_int 1) (const_int 1) (const_int 1) (const_int 1) + (const_int 1) (const_int 1) (const_int 1) (const_int 1)])) + (const_int 2)) + (const_vector:V8HI [(const_int 0) (const_int 0) (const_int 0) (const_int 0) + (const_int 0) (const_int 0) (const_int 0) (const_int 0)]) + (const_int 254)) + (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 4) + (const_int 5) (const_int 6) (const_int 7) (const_int 0)]))))] + "TARGET_REALLY_IWMMXT" + "wavg4%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wavg4")] +) + +(define_insn "iwmmxt_avg4r" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (truncate:V8QI + (vec_select:V8HI + (vec_merge:V8HI + (lshiftrt:V8HI + (plus:V8HI + (plus:V8HI + (plus:V8HI + (plus:V8HI + (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y"))) + (vec_select:V8HI (zero_extend:V8HI (match_dup 1)) + (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2) + (const_int 3) (const_int 4) (const_int 5) (const_int 6)]))) + (vec_select:V8HI (zero_extend:V8HI (match_dup 2)) + (parallel [(const_int 7) (const_int 0) (const_int 1) (const_int 2) + (const_int 3) (const_int 4) (const_int 5) (const_int 6)]))) + (const_vector:V8HI [(const_int 2) (const_int 2) (const_int 2) (const_int 2) + (const_int 2) (const_int 2) (const_int 2) (const_int 2)])) + (const_int 2)) + (const_vector:V8HI [(const_int 0) (const_int 0) (const_int 0) (const_int 0) + (const_int 0) (const_int 0) (const_int 0) (const_int 0)]) + (const_int 254)) + (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 4) + (const_int 5) (const_int 6) (const_int 7) (const_int 0)]))))] + "TARGET_REALLY_IWMMXT" + "wavg4r%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wavg4")] +) + +(define_insn "iwmmxt_wmaddsx" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (plus:V2SI + (mult:V2SI + (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 1) (const_int 3)])) + (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")) + (parallel [(const_int 0) (const_int 2)]))) + (mult:V2SI + (vec_select:V2SI (sign_extend:V4SI (match_dup 1)) + (parallel [(const_int 0) (const_int 2)])) + (vec_select:V2SI (sign_extend:V4SI (match_dup 2)) + (parallel [(const_int 1) (const_int 3)])))))] + "TARGET_REALLY_IWMMXT" + "wmaddsx%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmadd")] +) + +(define_insn "iwmmxt_wmaddux" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (plus:V2SI + (mult:V2SI + (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 1) (const_int 3)])) + (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")) + (parallel [(const_int 0) (const_int 2)]))) + (mult:V2SI + (vec_select:V2SI (zero_extend:V4SI (match_dup 1)) + (parallel [(const_int 0) (const_int 2)])) + (vec_select:V2SI (zero_extend:V4SI (match_dup 2)) + (parallel [(const_int 1) (const_int 3)])))))] + "TARGET_REALLY_IWMMXT" + "wmaddux%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmadd")] +) + +(define_insn "iwmmxt_wmaddsn" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (minus:V2SI + (mult:V2SI + (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 0) (const_int 2)])) + (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")) + (parallel [(const_int 0) (const_int 2)]))) + (mult:V2SI + (vec_select:V2SI (sign_extend:V4SI (match_dup 1)) + (parallel [(const_int 1) (const_int 3)])) + (vec_select:V2SI (sign_extend:V4SI (match_dup 2)) + (parallel [(const_int 1) (const_int 3)])))))] + "TARGET_REALLY_IWMMXT" + "wmaddsn%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmadd")] +) + +(define_insn "iwmmxt_wmaddun" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (minus:V2SI + (mult:V2SI + (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 0) (const_int 2)])) + (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")) + (parallel [(const_int 0) (const_int 2)]))) + (mult:V2SI + (vec_select:V2SI (zero_extend:V4SI (match_dup 1)) + (parallel [(const_int 1) (const_int 3)])) + (vec_select:V2SI (zero_extend:V4SI (match_dup 2)) + (parallel [(const_int 1) (const_int 3)])))))] + "TARGET_REALLY_IWMMXT" + "wmaddun%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmadd")] +) + +(define_insn "iwmmxt_wmulwsm" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (truncate:V2SI + (ashiftrt:V2DI + (mult:V2DI + (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (sign_extend:V2DI (match_operand:V2SI 2 "register_operand" "y"))) + (const_int 32))))] + "TARGET_REALLY_IWMMXT" + "wmulwsm%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmulw")] +) + +(define_insn "iwmmxt_wmulwum" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (truncate:V2SI + (lshiftrt:V2DI + (mult:V2DI + (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (zero_extend:V2DI (match_operand:V2SI 2 "register_operand" "y"))) + (const_int 32))))] + "TARGET_REALLY_IWMMXT" + "wmulwum%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmulw")] +) + +(define_insn "iwmmxt_wmulsmr" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (ashiftrt:V4SI + (plus:V4SI + (mult:V4SI + (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) + (const_vector:V4SI [(const_int 32768) + (const_int 32768) + (const_int 32768)])) + (const_int 16))))] + "TARGET_REALLY_IWMMXT" + "wmulsmr%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmul")] +) + +(define_insn "iwmmxt_wmulumr" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (mult:V4SI + (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) + (const_vector:V4SI [(const_int 32768) + (const_int 32768) + (const_int 32768) + (const_int 32768)])) + (const_int 16))))] + "TARGET_REALLY_IWMMXT" + "wmulumr%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmul")] +) + +(define_insn "iwmmxt_wmulwsmr" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (truncate:V2SI + (ashiftrt:V2DI + (plus:V2DI + (mult:V2DI + (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (sign_extend:V2DI (match_operand:V2SI 2 "register_operand" "y"))) + (const_vector:V2DI [(const_int 2147483648) + (const_int 2147483648)])) + (const_int 32))))] + "TARGET_REALLY_IWMMXT" + "wmulwsmr%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmul")] +) + +(define_insn "iwmmxt_wmulwumr" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (truncate:V2SI + (lshiftrt:V2DI + (plus:V2DI + (mult:V2DI + (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (zero_extend:V2DI (match_operand:V2SI 2 "register_operand" "y"))) + (const_vector:V2DI [(const_int 2147483648) + (const_int 2147483648)])) + (const_int 32))))] + "TARGET_REALLY_IWMMXT" + "wmulwumr%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmulw")] +) + +(define_insn "iwmmxt_wmulwl" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (mult:V2SI + (match_operand:V2SI 1 "register_operand" "y") + (match_operand:V2SI 2 "register_operand" "y")))] + "TARGET_REALLY_IWMMXT" + "wmulwl%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmulw")] +) + +(define_insn "iwmmxt_wqmulm" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y") + (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WQMULM))] + "TARGET_REALLY_IWMMXT" + "wqmulm%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmulm")] +) + +(define_insn "iwmmxt_wqmulwm" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "y") + (match_operand:V2SI 2 "register_operand" "y")] UNSPEC_WQMULWM))] + "TARGET_REALLY_IWMMXT" + "wqmulwm%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmulwm")] +) + +(define_insn "iwmmxt_wqmulmr" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y") + (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WQMULMR))] + "TARGET_REALLY_IWMMXT" + "wqmulmr%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmulm")] +) + +(define_insn "iwmmxt_wqmulwmr" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "y") + (match_operand:V2SI 2 "register_operand" "y")] UNSPEC_WQMULWMR))] + "TARGET_REALLY_IWMMXT" + "wqmulwmr%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmulwm")] +) + +(define_insn "iwmmxt_waddbhusm" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (vec_concat:V8QI + (const_vector:V4QI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)]) + (us_truncate:V4QI + (ss_plus:V4HI + (match_operand:V4HI 1 "register_operand" "y") + (zero_extend:V4HI + (vec_select:V4QI (match_operand:V8QI 2 "register_operand" "y") + (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)])))))))] + "TARGET_REALLY_IWMMXT" + "waddbhusm%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "waddbhus")] +) + +(define_insn "iwmmxt_waddbhusl" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (vec_concat:V8QI + (us_truncate:V4QI + (ss_plus:V4HI + (match_operand:V4HI 1 "register_operand" "y") + (zero_extend:V4HI + (vec_select:V4QI (match_operand:V8QI 2 "register_operand" "y") + (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))))) + (const_vector:V4QI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)])))] + "TARGET_REALLY_IWMMXT" + "waddbhusl%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "waddbhus")] +) + +(define_insn "iwmmxt_wqmiabb" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxy))] + "TARGET_REALLY_IWMMXT" + "wqmiabb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiabt" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxy))] + "TARGET_REALLY_IWMMXT" + "wqmiabt%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiatb" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxy))] + "TARGET_REALLY_IWMMXT" + "wqmiatb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiatt" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxy))] + "TARGET_REALLY_IWMMXT" + "wqmiatt%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiabbn" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxyn))] + "TARGET_REALLY_IWMMXT" + "wqmiabbn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiabtn" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 32)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxyn))] + "TARGET_REALLY_IWMMXT" + "wqmiabtn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiatbn" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 0)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 32))] UNSPEC_WQMIAxyn))] + "TARGET_REALLY_IWMMXT" + "wqmiatbn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wqmiattn" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "0") + (zero_extract:V4HI (match_operand:V4HI 2 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 2) (const_int 16) (const_int 48)) + (zero_extract:V4HI (match_operand:V4HI 3 "register_operand" "y") (const_int 16) (const_int 16)) + (zero_extract:V4HI (match_dup 3) (const_int 16) (const_int 48))] UNSPEC_WQMIAxyn))] + "TARGET_REALLY_IWMMXT" + "wqmiattn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wqmiaxy")] +) + +(define_insn "iwmmxt_wmiabb" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 0)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 0)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 2)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 2)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiabb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiabt" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 0)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 1)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 2)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 3)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiabt%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiatb" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 1)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 0)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 3)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 2)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiatb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiatt" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 1)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 1)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 3)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 3)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiatt%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiabbn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 0)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 0)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 2)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 2)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiabbn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiabtn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 0)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 1)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 2)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 3)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiabtn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiatbn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 1)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 0)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 3)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 2)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiatbn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiattn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (plus:DI + (mult:DI + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 1)]))) + (sign_extend:DI + (vec_select:HI (match_operand:V4HI 3 "register_operand" "y") + (parallel [(const_int 1)])))) + (mult:DI + (sign_extend:DI + (vec_select:HI (match_dup 2) + (parallel [(const_int 3)]))) + (sign_extend:DI + (vec_select:HI (match_dup 3) + (parallel [(const_int 3)])))))))] + "TARGET_REALLY_IWMMXT" + "wmiattn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiaxy")] +) + +(define_insn "iwmmxt_wmiawbb" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawbb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawbt" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawbt%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawtb" + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawtb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawtt" +[(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawtt%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawbbn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawbbn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawbtn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 0)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawbtn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawtbn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 0)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawtbn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmiawttn" + [(set (match_operand:DI 0 "register_operand" "=y") + (minus:DI + (match_operand:DI 1 "register_operand" "0") + (mult:DI + (sign_extend:DI (vec_select:SI (match_operand:V2SI 2 "register_operand" "y") (parallel [(const_int 1)]))) + (sign_extend:DI (vec_select:SI (match_operand:V2SI 3 "register_operand" "y") (parallel [(const_int 1)]))))))] + "TARGET_REALLY_IWMMXT" + "wmiawttn%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmiawxy")] +) + +(define_insn "iwmmxt_wmerge" + [(set (match_operand:DI 0 "register_operand" "=y") + (ior:DI + (ashift:DI + (match_operand:DI 2 "register_operand" "y") + (minus:SI + (const_int 64) + (mult:SI + (match_operand:SI 3 "immediate_operand" "i") + (const_int 8)))) + (lshiftrt:DI + (ashift:DI + (match_operand:DI 1 "register_operand" "y") + (mult:SI + (match_dup 3) + (const_int 8))) + (mult:SI + (match_dup 3) + (const_int 8)))))] + "TARGET_REALLY_IWMMXT" + "wmerge%?\\t%0, %1, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmerge")] +) + +(define_insn "iwmmxt_tandc3" + [(set (reg:CC CC_REGNUM) + (subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TANDC) 0)) + (unspec:CC [(reg:SI 15)] UNSPEC_TANDC)] + "TARGET_REALLY_IWMMXT" + "tandc%?\\t r15" + [(set_attr "predicable" "yes") + (set_attr "wtype" "tandc")] +) + +(define_insn "iwmmxt_torc3" + [(set (reg:CC CC_REGNUM) + (subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TORC) 0)) + (unspec:CC [(reg:SI 15)] UNSPEC_TORC)] + "TARGET_REALLY_IWMMXT" + "torc%?\\t r15" + [(set_attr "predicable" "yes") + (set_attr "wtype" "torc")] +) + +(define_insn "iwmmxt_torvsc3" + [(set (reg:CC CC_REGNUM) + (subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TORVSC) 0)) + (unspec:CC [(reg:SI 15)] UNSPEC_TORVSC)] + "TARGET_REALLY_IWMMXT" + "torvsc%?\\t r15" + [(set_attr "predicable" "yes") + (set_attr "wtype" "torvsc")] +) + +(define_insn "iwmmxt_textrc3" + [(set (reg:CC CC_REGNUM) + (subreg:CC (unspec:VMMX [(const_int 0) + (match_operand:SI 0 "immediate_operand" "i")] UNSPEC_TEXTRC) 0)) + (unspec:CC [(reg:SI 15)] UNSPEC_TEXTRC)] + "TARGET_REALLY_IWMMXT" + "textrc%?\\t r15, %0" + [(set_attr "predicable" "yes") + (set_attr "wtype" "textrc")] +) diff -ruN gcc/config/arm/iwmmxt.md gcc/config/arm/iwmmxt.md --- gcc/config/arm/iwmmxt.md 2011-08-15 04:57:33.000000000 -0700 +++ gcc/config/arm/iwmmxt.md 2013-01-27 20:14:06.009979280 -0800 @@ -1,6 +1,5 @@ -;; ??? This file needs auditing for thumb2 ;; Patterns for the Intel Wireless MMX technology architecture. -;; Copyright (C) 2003, 2004, 2005, 2007, 2008, 2010 +;; Copyright (C) 2003, 2004, 2005, 2007, 2008, 2010, 2012 ;; Free Software Foundation, Inc. ;; Contributed by Red Hat. @@ -20,6 +19,41 @@ ;; along with GCC; see the file COPYING3. If not see ;; . +;; Register numbers +(define_constants + [(WCGR0 43) + (WCGR1 44) + (WCGR2 45) + (WCGR3 46) + ] +) + +(define_insn "tbcstv8qi" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (vec_duplicate:V8QI (match_operand:QI 1 "s_register_operand" "r")))] + "TARGET_REALLY_IWMMXT" + "tbcstb%?\\t%0, %1" + [(set_attr "predicable" "yes") + (set_attr "wtype" "tbcst")] +) + +(define_insn "tbcstv4hi" + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_duplicate:V4HI (match_operand:HI 1 "s_register_operand" "r")))] + "TARGET_REALLY_IWMMXT" + "tbcsth%?\\t%0, %1" + [(set_attr "predicable" "yes") + (set_attr "wtype" "tbcst")] +) + +(define_insn "tbcstv2si" + [(set (match_operand:V2SI 0 "register_operand" "=y") + (vec_duplicate:V2SI (match_operand:SI 1 "s_register_operand" "r")))] + "TARGET_REALLY_IWMMXT" + "tbcstw%?\\t%0, %1" + [(set_attr "predicable" "yes") + (set_attr "wtype" "tbcst")] +) (define_insn "iwmmxt_iordi3" [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r") @@ -31,7 +65,9 @@ # #" [(set_attr "predicable" "yes") - (set_attr "length" "4,8,8")]) + (set_attr "length" "4,8,8") + (set_attr "wtype" "wor,none,none")] +) (define_insn "iwmmxt_xordi3" [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r") @@ -43,7 +79,9 @@ # #" [(set_attr "predicable" "yes") - (set_attr "length" "4,8,8")]) + (set_attr "length" "4,8,8") + (set_attr "wtype" "wxor,none,none")] +) (define_insn "iwmmxt_anddi3" [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r") @@ -55,7 +93,9 @@ # #" [(set_attr "predicable" "yes") - (set_attr "length" "4,8,8")]) + (set_attr "length" "4,8,8") + (set_attr "wtype" "wand,none,none")] +) (define_insn "iwmmxt_nanddi3" [(set (match_operand:DI 0 "register_operand" "=y") @@ -63,64 +103,96 @@ (not:DI (match_operand:DI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wandn%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wandn")] +) (define_insn "*iwmmxt_arm_movdi" - [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, m,y,y,yr,y,yrUy") - (match_operand:DI 1 "di_operand" "rIK,mi,r,y,yr,y,yrUy,y"))] + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m,y,y,yr,y,yrUy,*w, r,*w,*w, *Uv") + (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r,y,yr,y,yrUy,y, r,*w,*w,*Uvi,*w"))] "TARGET_REALLY_IWMMXT && ( register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" "* -{ switch (which_alternative) { - default: - return output_move_double (operands, true, NULL); case 0: + case 1: + case 2: return \"#\"; - case 3: + case 3: case 4: + return output_move_double (operands, true, NULL); + case 5: return \"wmov%?\\t%0,%1\"; - case 4: + case 6: return \"tmcrr%?\\t%0,%Q1,%R1\"; - case 5: + case 7: return \"tmrrc%?\\t%Q0,%R0,%1\"; - case 6: + case 8: return \"wldrd%?\\t%0,%1\"; - case 7: + case 9: return \"wstrd%?\\t%1,%0\"; + case 10: + return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\"; + case 11: + return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; + case 12: + if (TARGET_VFP_SINGLE) + return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\"; + else + return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; + case 13: case 14: + return output_move_vfp (operands); + default: + gcc_unreachable (); } -}" - [(set_attr "length" "8,8,8,4,4,4,4,4") - (set_attr "type" "*,load1,store2,*,*,*,*,*") - (set_attr "pool_range" "*,1020,*,*,*,*,*,*") - (set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")] + " + [(set (attr "length") (cond [(eq_attr "alternative" "0,3,4") (const_int 8) + (eq_attr "alternative" "1") (const_int 12) + (eq_attr "alternative" "2") (const_int 16) + (eq_attr "alternative" "12") + (if_then_else + (eq (symbol_ref "TARGET_VFP_SINGLE") (const_int 1)) + (const_int 8) + (const_int 4))] + (const_int 4))) + (set_attr "type" "*,*,*,load2,store2,*,*,*,*,*,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") + (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,*,*,*,*,*,*,1020,*") + (set_attr "arm_neg_pool_range" "*,*,*,1008,*,*,*,*,*,*,*,*,*,1008,*") + (set_attr "wtype" "*,*,*,*,*,wmov,tmcrr,tmrrc,wldr,wstr,*,*,*,*,*")] ) (define_insn "*iwmmxt_movsi_insn" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,rk, m,z,r,?z,Uy,z") - (match_operand:SI 1 "general_operand" "rk, I,K,mi,rk,r,z,Uy,z, z"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk, m,z,r,?z,?Uy,*t, r,*t,*t ,*Uv") + (match_operand:SI 1 "general_operand" " rk,I,K,j,mi,rk,r,z,Uy, z, r,*t,*t,*Uvi, *t"))] "TARGET_REALLY_IWMMXT && ( register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" "* switch (which_alternative) - { - case 0: return \"mov\\t%0, %1\"; - case 1: return \"mov\\t%0, %1\"; - case 2: return \"mvn\\t%0, #%B1\"; - case 3: return \"ldr\\t%0, %1\"; - case 4: return \"str\\t%1, %0\"; - case 5: return \"tmcr\\t%0, %1\"; - case 6: return \"tmrc\\t%0, %1\"; - case 7: return arm_output_load_gr (operands); - case 8: return \"wstrw\\t%1, %0\"; - default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\"; - }" - [(set_attr "type" "*,*,*,load1,store1,*,*,load1,store1,*") - (set_attr "length" "*,*,*,*, *,*,*, 16, *,8") - (set_attr "pool_range" "*,*,*,4096, *,*,*,1024, *,*") - (set_attr "neg_pool_range" "*,*,*,4084, *,*,*, *, 1012,*") + { + case 0: return \"mov\\t%0, %1\"; + case 1: return \"mov\\t%0, %1\"; + case 2: return \"mvn\\t%0, #%B1\"; + case 3: return \"movw\\t%0, %1\"; + case 4: return \"ldr\\t%0, %1\"; + case 5: return \"str\\t%1, %0\"; + case 6: return \"tmcr\\t%0, %1\"; + case 7: return \"tmrc\\t%0, %1\"; + case 8: return arm_output_load_gr (operands); + case 9: return \"wstrw\\t%1, %0\"; + case 10:return \"fmsr\\t%0, %1\"; + case 11:return \"fmrs\\t%0, %1\"; + case 12:return \"fcpys\\t%0, %1\\t%@ int\"; + case 13: case 14: + return output_move_vfp (operands); + default: + gcc_unreachable (); + }" + [(set_attr "type" "*,*,*,*,load1,store1,*,*,*,*,r_2_f,f_2_r,fcpys,f_loads,f_stores") + (set_attr "length" "*,*,*,*,*, *,*,*, 16, *,*,*,*,*,*") + (set_attr "pool_range" "*,*,*,*,4096, *,*,*,1024, *,*,*,*,1020,*") + (set_attr "neg_pool_range" "*,*,*,*,4084, *,*,*, *, 1012,*,*,*,1008,*") ;; Note - the "predicable" attribute is not allowed to have alternatives. ;; Since the wSTRw wCx instruction is not predicable, we cannot support ;; predicating any of the alternatives in this template. Instead, @@ -129,7 +201,8 @@ ;; Also - we have to pretend that these insns clobber the condition code ;; bits as otherwise arm_final_prescan_insn() will try to conditionalize ;; them. - (set_attr "conds" "clob")] + (set_attr "conds" "clob") + (set_attr "wtype" "*,*,*,*,*,*,tmcr,tmrc,wldr,wstr,*,*,*,*,*")] ) ;; Because iwmmxt_movsi_insn is not predicable, we provide the @@ -177,19 +250,110 @@ }" [(set_attr "predicable" "yes") (set_attr "length" "4, 4, 4,4,4,8, 8,8") - (set_attr "type" "*,store1,load1,*,*,*,load1,store1") + (set_attr "type" "*,*,*,*,*,*,load1,store1") (set_attr "pool_range" "*, *, 256,*,*,*, 256,*") - (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")]) + (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*") + (set_attr "wtype" "wmov,wstr,wldr,tmrrc,tmcrr,*,*,*")] +) + +(define_expand "iwmmxt_setwcgr0" + [(set (reg:SI WCGR0) + (match_operand:SI 0 "register_operand" ""))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_setwcgr1" + [(set (reg:SI WCGR1) + (match_operand:SI 0 "register_operand" ""))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_setwcgr2" + [(set (reg:SI WCGR2) + (match_operand:SI 0 "register_operand" ""))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_setwcgr3" + [(set (reg:SI WCGR3) + (match_operand:SI 0 "register_operand" ""))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_getwcgr0" + [(set (match_operand:SI 0 "register_operand" "") + (reg:SI WCGR0))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_getwcgr1" + [(set (match_operand:SI 0 "register_operand" "") + (reg:SI WCGR1))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_getwcgr2" + [(set (match_operand:SI 0 "register_operand" "") + (reg:SI WCGR2))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_expand "iwmmxt_getwcgr3" + [(set (match_operand:SI 0 "register_operand" "") + (reg:SI WCGR3))] + "TARGET_REALLY_IWMMXT" + {} +) + +(define_insn "*and3_iwmmxt" + [(set (match_operand:VMMX 0 "register_operand" "=y") + (and:VMMX (match_operand:VMMX 1 "register_operand" "y") + (match_operand:VMMX 2 "register_operand" "y")))] + "TARGET_REALLY_IWMMXT" + "wand\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wand")] +) + +(define_insn "*ior3_iwmmxt" + [(set (match_operand:VMMX 0 "register_operand" "=y") + (ior:VMMX (match_operand:VMMX 1 "register_operand" "y") + (match_operand:VMMX 2 "register_operand" "y")))] + "TARGET_REALLY_IWMMXT" + "wor\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wor")] +) + +(define_insn "*xor3_iwmmxt" + [(set (match_operand:VMMX 0 "register_operand" "=y") + (xor:VMMX (match_operand:VMMX 1 "register_operand" "y") + (match_operand:VMMX 2 "register_operand" "y")))] + "TARGET_REALLY_IWMMXT" + "wxor\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wxor")] +) + ;; Vector add/subtract (define_insn "*add3_iwmmxt" [(set (match_operand:VMMX 0 "register_operand" "=y") - (plus:VMMX (match_operand:VMMX 1 "register_operand" "y") - (match_operand:VMMX 2 "register_operand" "y")))] + (plus:VMMX (match_operand:VMMX 1 "register_operand" "y") + (match_operand:VMMX 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wadd%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "ssaddv8qi3" [(set (match_operand:V8QI 0 "register_operand" "=y") @@ -197,7 +361,9 @@ (match_operand:V8QI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "waddbss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "ssaddv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") @@ -205,7 +371,9 @@ (match_operand:V4HI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "waddhss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "ssaddv2si3" [(set (match_operand:V2SI 0 "register_operand" "=y") @@ -213,7 +381,9 @@ (match_operand:V2SI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "waddwss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "usaddv8qi3" [(set (match_operand:V8QI 0 "register_operand" "=y") @@ -221,7 +391,9 @@ (match_operand:V8QI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "waddbus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "usaddv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") @@ -229,7 +401,9 @@ (match_operand:V4HI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "waddhus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "usaddv2si3" [(set (match_operand:V2SI 0 "register_operand" "=y") @@ -237,7 +411,9 @@ (match_operand:V2SI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "waddwus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wadd")] +) (define_insn "*sub3_iwmmxt" [(set (match_operand:VMMX 0 "register_operand" "=y") @@ -245,7 +421,9 @@ (match_operand:VMMX 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsub%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "sssubv8qi3" [(set (match_operand:V8QI 0 "register_operand" "=y") @@ -253,7 +431,9 @@ (match_operand:V8QI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsubbss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "sssubv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") @@ -261,7 +441,9 @@ (match_operand:V4HI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsubhss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "sssubv2si3" [(set (match_operand:V2SI 0 "register_operand" "=y") @@ -269,7 +451,9 @@ (match_operand:V2SI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsubwss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "ussubv8qi3" [(set (match_operand:V8QI 0 "register_operand" "=y") @@ -277,7 +461,9 @@ (match_operand:V8QI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsubbus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "ussubv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") @@ -285,7 +471,9 @@ (match_operand:V4HI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsubhus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "ussubv2si3" [(set (match_operand:V2SI 0 "register_operand" "=y") @@ -293,7 +481,9 @@ (match_operand:V2SI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wsubwus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsub")] +) (define_insn "*mulv4hi3_iwmmxt" [(set (match_operand:V4HI 0 "register_operand" "=y") @@ -301,63 +491,77 @@ (match_operand:V4HI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wmulul%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmul")] +) (define_insn "smulv4hi3_highpart" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (truncate:V4HI - (lshiftrt:V4SI - (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) - (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) - (const_int 16))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (lshiftrt:V4SI + (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) + (const_int 16))))] "TARGET_REALLY_IWMMXT" "wmulsm%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmul")] +) (define_insn "umulv4hi3_highpart" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (truncate:V4HI - (lshiftrt:V4SI - (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) - (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) - (const_int 16))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (lshiftrt:V4SI + (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) + (const_int 16))))] "TARGET_REALLY_IWMMXT" "wmulum%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmul")] +) (define_insn "iwmmxt_wmacs" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:DI 1 "register_operand" "0") - (match_operand:V4HI 2 "register_operand" "y") - (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACS))] + (match_operand:V4HI 2 "register_operand" "y") + (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACS))] "TARGET_REALLY_IWMMXT" "wmacs%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmac")] +) (define_insn "iwmmxt_wmacsz" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACSZ))] + (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACSZ))] "TARGET_REALLY_IWMMXT" "wmacsz%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmac")] +) (define_insn "iwmmxt_wmacu" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:DI 1 "register_operand" "0") - (match_operand:V4HI 2 "register_operand" "y") - (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACU))] + (match_operand:V4HI 2 "register_operand" "y") + (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACU))] "TARGET_REALLY_IWMMXT" "wmacu%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmac")] +) (define_insn "iwmmxt_wmacuz" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACUZ))] + (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACUZ))] "TARGET_REALLY_IWMMXT" "wmacuz%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmac")] +) ;; Same as xordi3, but don't show input operands so that we don't think ;; they are live. @@ -366,168 +570,207 @@ (unspec:DI [(const_int 0)] UNSPEC_CLRDI))] "TARGET_REALLY_IWMMXT" "wxor%?\\t%0, %0, %0" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wxor")] +) ;; Seems like cse likes to generate these, so we have to support them. -(define_insn "*iwmmxt_clrv8qi" - [(set (match_operand:V8QI 0 "register_operand" "=y") +(define_insn "iwmmxt_clrv8qi" + [(set (match_operand:V8QI 0 "s_register_operand" "=y") (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0) (const_int 0) (const_int 0) (const_int 0) (const_int 0) (const_int 0)]))] "TARGET_REALLY_IWMMXT" "wxor%?\\t%0, %0, %0" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wxor")] +) -(define_insn "*iwmmxt_clrv4hi" - [(set (match_operand:V4HI 0 "register_operand" "=y") +(define_insn "iwmmxt_clrv4hi" + [(set (match_operand:V4HI 0 "s_register_operand" "=y") (const_vector:V4HI [(const_int 0) (const_int 0) (const_int 0) (const_int 0)]))] "TARGET_REALLY_IWMMXT" "wxor%?\\t%0, %0, %0" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wxor")] +) -(define_insn "*iwmmxt_clrv2si" +(define_insn "iwmmxt_clrv2si" [(set (match_operand:V2SI 0 "register_operand" "=y") (const_vector:V2SI [(const_int 0) (const_int 0)]))] "TARGET_REALLY_IWMMXT" "wxor%?\\t%0, %0, %0" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wxor")] +) ;; Unsigned averages/sum of absolute differences (define_insn "iwmmxt_uavgrndv8qi3" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (ashiftrt:V8QI - (plus:V8QI (plus:V8QI - (match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y")) - (const_vector:V8QI [(const_int 1) - (const_int 1) - (const_int 1) - (const_int 1) - (const_int 1) - (const_int 1) - (const_int 1) - (const_int 1)])) - (const_int 1)))] + [(set (match_operand:V8QI 0 "register_operand" "=y") + (truncate:V8QI + (lshiftrt:V8HI + (plus:V8HI + (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y"))) + (const_vector:V8HI [(const_int 1) + (const_int 1) + (const_int 1) + (const_int 1) + (const_int 1) + (const_int 1) + (const_int 1) + (const_int 1)])) + (const_int 1))))] "TARGET_REALLY_IWMMXT" "wavg2br%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wavg2")] +) (define_insn "iwmmxt_uavgrndv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (ashiftrt:V4HI - (plus:V4HI (plus:V4HI - (match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")) - (const_vector:V4HI [(const_int 1) - (const_int 1) - (const_int 1) - (const_int 1)])) - (const_int 1)))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (plus:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) + (const_vector:V4SI [(const_int 1) + (const_int 1) + (const_int 1) + (const_int 1)])) + (const_int 1))))] "TARGET_REALLY_IWMMXT" "wavg2hr%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - + [(set_attr "predicable" "yes") + (set_attr "wtype" "wavg2")] +) (define_insn "iwmmxt_uavgv8qi3" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (ashiftrt:V8QI (plus:V8QI - (match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y")) - (const_int 1)))] + [(set (match_operand:V8QI 0 "register_operand" "=y") + (truncate:V8QI + (lshiftrt:V8HI + (plus:V8HI (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (zero_extend:V8HI (match_operand:V8QI 2 "register_operand" "y"))) + (const_int 1))))] "TARGET_REALLY_IWMMXT" "wavg2b%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wavg2")] +) (define_insn "iwmmxt_uavgv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (ashiftrt:V4HI (plus:V4HI - (match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")) - (const_int 1)))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y"))) + (const_int 1))))] "TARGET_REALLY_IWMMXT" "wavg2h%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "iwmmxt_psadbw" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y"))))] - "TARGET_REALLY_IWMMXT" - "psadbw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - + [(set_attr "predicable" "yes") + (set_attr "wtype" "wavg2")] +) ;; Insert/extract/shuffle (define_insn "iwmmxt_tinsrb" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (vec_merge:V8QI (match_operand:V8QI 1 "register_operand" "0") - (vec_duplicate:V8QI - (truncate:QI (match_operand:SI 2 "nonimmediate_operand" "r"))) - (match_operand:SI 3 "immediate_operand" "i")))] + [(set (match_operand:V8QI 0 "register_operand" "=y") + (vec_merge:V8QI + (vec_duplicate:V8QI + (truncate:QI (match_operand:SI 2 "nonimmediate_operand" "r"))) + (match_operand:V8QI 1 "register_operand" "0") + (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_REALLY_IWMMXT" - "tinsrb%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + "* + { + return arm_output_iwmmxt_tinsr (operands); + } + " + [(set_attr "predicable" "yes") + (set_attr "wtype" "tinsr")] +) (define_insn "iwmmxt_tinsrh" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0") - (vec_duplicate:V4HI - (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "r"))) - (match_operand:SI 3 "immediate_operand" "i")))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_merge:V4HI + (vec_duplicate:V4HI + (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "r"))) + (match_operand:V4HI 1 "register_operand" "0") + (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_REALLY_IWMMXT" - "tinsrh%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + "* + { + return arm_output_iwmmxt_tinsr (operands); + } + " + [(set_attr "predicable" "yes") + (set_attr "wtype" "tinsr")] +) (define_insn "iwmmxt_tinsrw" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (vec_merge:V2SI (match_operand:V2SI 1 "register_operand" "0") - (vec_duplicate:V2SI - (match_operand:SI 2 "nonimmediate_operand" "r")) - (match_operand:SI 3 "immediate_operand" "i")))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (vec_merge:V2SI + (vec_duplicate:V2SI + (match_operand:SI 2 "nonimmediate_operand" "r")) + (match_operand:V2SI 1 "register_operand" "0") + (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_REALLY_IWMMXT" - "tinsrw%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + "* + { + return arm_output_iwmmxt_tinsr (operands); + } + " + [(set_attr "predicable" "yes") + (set_attr "wtype" "tinsr")] +) (define_insn "iwmmxt_textrmub" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y") - (parallel - [(match_operand:SI 2 "immediate_operand" "i")]))))] + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y") + (parallel + [(match_operand:SI 2 "immediate_operand" "i")]))))] "TARGET_REALLY_IWMMXT" "textrmub%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "textrm")] +) (define_insn "iwmmxt_textrmsb" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y") + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y") (parallel - [(match_operand:SI 2 "immediate_operand" "i")]))))] + [(match_operand:SI 2 "immediate_operand" "i")]))))] "TARGET_REALLY_IWMMXT" "textrmsb%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "textrm")] +) (define_insn "iwmmxt_textrmuh" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y") + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y") (parallel - [(match_operand:SI 2 "immediate_operand" "i")]))))] + [(match_operand:SI 2 "immediate_operand" "i")]))))] "TARGET_REALLY_IWMMXT" "textrmuh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "textrm")] +) (define_insn "iwmmxt_textrmsh" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y") + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y") (parallel - [(match_operand:SI 2 "immediate_operand" "i")]))))] + [(match_operand:SI 2 "immediate_operand" "i")]))))] "TARGET_REALLY_IWMMXT" "textrmsh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "textrm")] +) ;; There are signed/unsigned variants of this instruction, but they are ;; pointless. @@ -537,7 +780,9 @@ (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] "TARGET_REALLY_IWMMXT" "textrmsw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "textrm")] +) (define_insn "iwmmxt_wshufh" [(set (match_operand:V4HI 0 "register_operand" "=y") @@ -545,7 +790,9 @@ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_WSHUFH))] "TARGET_REALLY_IWMMXT" "wshufh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wshufh")] +) ;; Mask-generating comparisons ;; @@ -557,92 +804,106 @@ ;; into the entire destination vector, (with the '1' going into the least ;; significant element of the vector). This is not how these instructions ;; behave. -;; -;; Unfortunately the current patterns are illegal. They are SET insns -;; without a SET in them. They work in most cases for ordinary code -;; generation, but there are circumstances where they can cause gcc to fail. -;; XXX - FIXME. (define_insn "eqv8qi3" - [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y") - (match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y")] - VUNSPEC_WCMP_EQ)] + [(set (match_operand:V8QI 0 "register_operand" "=y") + (unspec_volatile:V8QI [(match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")] + VUNSPEC_WCMP_EQ))] "TARGET_REALLY_IWMMXT" "wcmpeqb%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpeq")] +) (define_insn "eqv4hi3" - [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y") - (match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] - VUNSPEC_WCMP_EQ)] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (unspec_volatile:V4HI [(match_operand:V4HI 1 "register_operand" "y") + (match_operand:V4HI 2 "register_operand" "y")] + VUNSPEC_WCMP_EQ))] "TARGET_REALLY_IWMMXT" "wcmpeqh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpeq")] +) (define_insn "eqv2si3" - [(unspec_volatile:V2SI [(match_operand:V2SI 0 "register_operand" "=y") - (match_operand:V2SI 1 "register_operand" "y") - (match_operand:V2SI 2 "register_operand" "y")] - VUNSPEC_WCMP_EQ)] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec_volatile:V2SI + [(match_operand:V2SI 1 "register_operand" "y") + (match_operand:V2SI 2 "register_operand" "y")] + VUNSPEC_WCMP_EQ))] "TARGET_REALLY_IWMMXT" "wcmpeqw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpeq")] +) (define_insn "gtuv8qi3" - [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y") - (match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y")] - VUNSPEC_WCMP_GTU)] + [(set (match_operand:V8QI 0 "register_operand" "=y") + (unspec_volatile:V8QI [(match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")] + VUNSPEC_WCMP_GTU))] "TARGET_REALLY_IWMMXT" "wcmpgtub%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpgt")] +) (define_insn "gtuv4hi3" - [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y") - (match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] - VUNSPEC_WCMP_GTU)] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (unspec_volatile:V4HI [(match_operand:V4HI 1 "register_operand" "y") + (match_operand:V4HI 2 "register_operand" "y")] + VUNSPEC_WCMP_GTU))] "TARGET_REALLY_IWMMXT" "wcmpgtuh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpgt")] +) (define_insn "gtuv2si3" - [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y") - (match_operand:V2SI 1 "register_operand" "y") - (match_operand:V2SI 2 "register_operand" "y")] - VUNSPEC_WCMP_GTU)] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec_volatile:V2SI [(match_operand:V2SI 1 "register_operand" "y") + (match_operand:V2SI 2 "register_operand" "y")] + VUNSPEC_WCMP_GTU))] "TARGET_REALLY_IWMMXT" "wcmpgtuw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpgt")] +) (define_insn "gtv8qi3" - [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y") - (match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y")] - VUNSPEC_WCMP_GT)] + [(set (match_operand:V8QI 0 "register_operand" "=y") + (unspec_volatile:V8QI [(match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")] + VUNSPEC_WCMP_GT))] "TARGET_REALLY_IWMMXT" "wcmpgtsb%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpgt")] +) (define_insn "gtv4hi3" - [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y") - (match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] - VUNSPEC_WCMP_GT)] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (unspec_volatile:V4HI [(match_operand:V4HI 1 "register_operand" "y") + (match_operand:V4HI 2 "register_operand" "y")] + VUNSPEC_WCMP_GT))] "TARGET_REALLY_IWMMXT" "wcmpgtsh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpgt")] +) (define_insn "gtv2si3" - [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y") - (match_operand:V2SI 1 "register_operand" "y") - (match_operand:V2SI 2 "register_operand" "y")] - VUNSPEC_WCMP_GT)] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec_volatile:V2SI [(match_operand:V2SI 1 "register_operand" "y") + (match_operand:V2SI 2 "register_operand" "y")] + VUNSPEC_WCMP_GT))] "TARGET_REALLY_IWMMXT" "wcmpgtsw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wcmpgt")] +) ;; Max/min insns @@ -652,7 +913,9 @@ (match_operand:VMMX 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wmaxs%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmax")] +) (define_insn "*umax3_iwmmxt" [(set (match_operand:VMMX 0 "register_operand" "=y") @@ -660,7 +923,9 @@ (match_operand:VMMX 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wmaxu%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmax")] +) (define_insn "*smin3_iwmmxt" [(set (match_operand:VMMX 0 "register_operand" "=y") @@ -668,7 +933,9 @@ (match_operand:VMMX 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wmins%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmin")] +) (define_insn "*umin3_iwmmxt" [(set (match_operand:VMMX 0 "register_operand" "=y") @@ -676,657 +943,835 @@ (match_operand:VMMX 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" "wminu%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmin")] +) ;; Pack/unpack insns. (define_insn "iwmmxt_wpackhss" - [(set (match_operand:V8QI 0 "register_operand" "=y") + [(set (match_operand:V8QI 0 "register_operand" "=y") (vec_concat:V8QI - (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y")) - (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))] + (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y")) + (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wpackhss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wpack")] +) (define_insn "iwmmxt_wpackwss" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (vec_concat:V4HI - (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y")) - (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_concat:V4HI + (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y")) + (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wpackwss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wpack")] +) (define_insn "iwmmxt_wpackdss" - [(set (match_operand:V2SI 0 "register_operand" "=y") + [(set (match_operand:V2SI 0 "register_operand" "=y") (vec_concat:V2SI - (ss_truncate:SI (match_operand:DI 1 "register_operand" "y")) - (ss_truncate:SI (match_operand:DI 2 "register_operand" "y"))))] + (ss_truncate:SI (match_operand:DI 1 "register_operand" "y")) + (ss_truncate:SI (match_operand:DI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wpackdss%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wpack")] +) (define_insn "iwmmxt_wpackhus" - [(set (match_operand:V8QI 0 "register_operand" "=y") + [(set (match_operand:V8QI 0 "register_operand" "=y") (vec_concat:V8QI - (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y")) - (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))] + (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y")) + (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wpackhus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wpack")] +) (define_insn "iwmmxt_wpackwus" - [(set (match_operand:V4HI 0 "register_operand" "=y") + [(set (match_operand:V4HI 0 "register_operand" "=y") (vec_concat:V4HI - (us_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y")) - (us_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))] + (us_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y")) + (us_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wpackwus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wpack")] +) (define_insn "iwmmxt_wpackdus" - [(set (match_operand:V2SI 0 "register_operand" "=y") + [(set (match_operand:V2SI 0 "register_operand" "=y") (vec_concat:V2SI - (us_truncate:SI (match_operand:DI 1 "register_operand" "y")) - (us_truncate:SI (match_operand:DI 2 "register_operand" "y"))))] + (us_truncate:SI (match_operand:DI 1 "register_operand" "y")) + (us_truncate:SI (match_operand:DI 2 "register_operand" "y"))))] "TARGET_REALLY_IWMMXT" "wpackdus%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - + [(set_attr "predicable" "yes") + (set_attr "wtype" "wpack")] +) (define_insn "iwmmxt_wunpckihb" - [(set (match_operand:V8QI 0 "register_operand" "=y") + [(set (match_operand:V8QI 0 "register_operand" "=y") (vec_merge:V8QI - (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y") - (parallel [(const_int 4) - (const_int 0) - (const_int 5) - (const_int 1) - (const_int 6) - (const_int 2) - (const_int 7) - (const_int 3)])) - (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y") - (parallel [(const_int 0) - (const_int 4) - (const_int 1) - (const_int 5) - (const_int 2) - (const_int 6) - (const_int 3) - (const_int 7)])) - (const_int 85)))] + (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y") + (parallel [(const_int 4) + (const_int 0) + (const_int 5) + (const_int 1) + (const_int 6) + (const_int 2) + (const_int 7) + (const_int 3)])) + (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y") + (parallel [(const_int 0) + (const_int 4) + (const_int 1) + (const_int 5) + (const_int 2) + (const_int 6) + (const_int 3) + (const_int 7)])) + (const_int 85)))] "TARGET_REALLY_IWMMXT" "wunpckihb%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckih")] +) (define_insn "iwmmxt_wunpckihh" - [(set (match_operand:V4HI 0 "register_operand" "=y") + [(set (match_operand:V4HI 0 "register_operand" "=y") (vec_merge:V4HI - (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y") - (parallel [(const_int 0) - (const_int 2) - (const_int 1) - (const_int 3)])) - (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") - (parallel [(const_int 2) - (const_int 0) - (const_int 3) - (const_int 1)])) - (const_int 5)))] + (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y") + (parallel [(const_int 2) + (const_int 0) + (const_int 3) + (const_int 1)])) + (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 0) + (const_int 2) + (const_int 1) + (const_int 3)])) + (const_int 5)))] "TARGET_REALLY_IWMMXT" "wunpckihh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckih")] +) (define_insn "iwmmxt_wunpckihw" - [(set (match_operand:V2SI 0 "register_operand" "=y") + [(set (match_operand:V2SI 0 "register_operand" "=y") (vec_merge:V2SI - (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y") - (parallel [(const_int 0) - (const_int 1)])) - (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y") - (parallel [(const_int 1) - (const_int 0)])) - (const_int 1)))] + (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y") + (parallel [(const_int 1) + (const_int 0)])) + (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y") + (parallel [(const_int 0) + (const_int 1)])) + (const_int 1)))] "TARGET_REALLY_IWMMXT" "wunpckihw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckih")] +) (define_insn "iwmmxt_wunpckilb" - [(set (match_operand:V8QI 0 "register_operand" "=y") + [(set (match_operand:V8QI 0 "register_operand" "=y") (vec_merge:V8QI - (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y") - (parallel [(const_int 0) - (const_int 4) - (const_int 1) - (const_int 5) - (const_int 2) - (const_int 6) - (const_int 3) - (const_int 7)])) - (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y") - (parallel [(const_int 4) - (const_int 0) - (const_int 5) - (const_int 1) - (const_int 6) - (const_int 2) - (const_int 7) - (const_int 3)])) - (const_int 85)))] + (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y") + (parallel [(const_int 0) + (const_int 4) + (const_int 1) + (const_int 5) + (const_int 2) + (const_int 6) + (const_int 3) + (const_int 7)])) + (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y") + (parallel [(const_int 4) + (const_int 0) + (const_int 5) + (const_int 1) + (const_int 6) + (const_int 2) + (const_int 7) + (const_int 3)])) + (const_int 85)))] "TARGET_REALLY_IWMMXT" "wunpckilb%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckil")] +) (define_insn "iwmmxt_wunpckilh" - [(set (match_operand:V4HI 0 "register_operand" "=y") + [(set (match_operand:V4HI 0 "register_operand" "=y") (vec_merge:V4HI - (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y") - (parallel [(const_int 2) - (const_int 0) - (const_int 3) - (const_int 1)])) - (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") - (parallel [(const_int 0) - (const_int 2) - (const_int 1) - (const_int 3)])) - (const_int 5)))] + (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y") + (parallel [(const_int 0) + (const_int 2) + (const_int 1) + (const_int 3)])) + (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y") + (parallel [(const_int 2) + (const_int 0) + (const_int 3) + (const_int 1)])) + (const_int 5)))] "TARGET_REALLY_IWMMXT" "wunpckilh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckil")] +) (define_insn "iwmmxt_wunpckilw" - [(set (match_operand:V2SI 0 "register_operand" "=y") + [(set (match_operand:V2SI 0 "register_operand" "=y") (vec_merge:V2SI - (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y") - (parallel [(const_int 1) - (const_int 0)])) - (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y") - (parallel [(const_int 0) - (const_int 1)])) - (const_int 1)))] + (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y") + (parallel [(const_int 0) + (const_int 1)])) + (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y") + (parallel [(const_int 1) + (const_int 0)])) + (const_int 1)))] "TARGET_REALLY_IWMMXT" "wunpckilw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckil")] +) (define_insn "iwmmxt_wunpckehub" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (zero_extend:V4HI - (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y") - (parallel [(const_int 4) (const_int 5) - (const_int 6) (const_int 7)]))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_select:V4HI + (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (parallel [(const_int 4) (const_int 5) + (const_int 6) (const_int 7)])))] "TARGET_REALLY_IWMMXT" "wunpckehub%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckeh")] +) (define_insn "iwmmxt_wunpckehuh" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (zero_extend:V2SI - (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y") - (parallel [(const_int 2) (const_int 3)]))))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (vec_select:V2SI + (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 2) (const_int 3)])))] "TARGET_REALLY_IWMMXT" "wunpckehuh%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckeh")] +) (define_insn "iwmmxt_wunpckehuw" - [(set (match_operand:DI 0 "register_operand" "=y") - (zero_extend:DI - (vec_select:SI (match_operand:V2SI 1 "register_operand" "y") - (parallel [(const_int 1)]))))] + [(set (match_operand:DI 0 "register_operand" "=y") + (vec_select:DI + (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (parallel [(const_int 1)])))] "TARGET_REALLY_IWMMXT" "wunpckehuw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckeh")] +) (define_insn "iwmmxt_wunpckehsb" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (sign_extend:V4HI - (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y") - (parallel [(const_int 4) (const_int 5) - (const_int 6) (const_int 7)]))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_select:V4HI + (sign_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (parallel [(const_int 4) (const_int 5) + (const_int 6) (const_int 7)])))] "TARGET_REALLY_IWMMXT" "wunpckehsb%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckeh")] +) (define_insn "iwmmxt_wunpckehsh" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (sign_extend:V2SI - (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y") - (parallel [(const_int 2) (const_int 3)]))))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (vec_select:V2SI + (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 2) (const_int 3)])))] "TARGET_REALLY_IWMMXT" "wunpckehsh%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckeh")] +) (define_insn "iwmmxt_wunpckehsw" - [(set (match_operand:DI 0 "register_operand" "=y") - (sign_extend:DI - (vec_select:SI (match_operand:V2SI 1 "register_operand" "y") - (parallel [(const_int 1)]))))] + [(set (match_operand:DI 0 "register_operand" "=y") + (vec_select:DI + (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (parallel [(const_int 1)])))] "TARGET_REALLY_IWMMXT" "wunpckehsw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckeh")] +) (define_insn "iwmmxt_wunpckelub" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (zero_extend:V4HI - (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y") - (parallel [(const_int 0) (const_int 1) - (const_int 2) (const_int 3)]))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_select:V4HI + (zero_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3)])))] "TARGET_REALLY_IWMMXT" "wunpckelub%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckel")] +) (define_insn "iwmmxt_wunpckeluh" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (zero_extend:V2SI - (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y") - (parallel [(const_int 0) (const_int 1)]))))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (vec_select:V2SI + (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 0) (const_int 1)])))] "TARGET_REALLY_IWMMXT" "wunpckeluh%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckel")] +) (define_insn "iwmmxt_wunpckeluw" - [(set (match_operand:DI 0 "register_operand" "=y") - (zero_extend:DI - (vec_select:SI (match_operand:V2SI 1 "register_operand" "y") - (parallel [(const_int 0)]))))] + [(set (match_operand:DI 0 "register_operand" "=y") + (vec_select:DI + (zero_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (parallel [(const_int 0)])))] "TARGET_REALLY_IWMMXT" "wunpckeluw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckel")] +) (define_insn "iwmmxt_wunpckelsb" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (sign_extend:V4HI - (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y") - (parallel [(const_int 0) (const_int 1) - (const_int 2) (const_int 3)]))))] + [(set (match_operand:V4HI 0 "register_operand" "=y") + (vec_select:V4HI + (sign_extend:V8HI (match_operand:V8QI 1 "register_operand" "y")) + (parallel [(const_int 0) (const_int 1) + (const_int 2) (const_int 3)])))] "TARGET_REALLY_IWMMXT" "wunpckelsb%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckel")] +) (define_insn "iwmmxt_wunpckelsh" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (sign_extend:V2SI - (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y") - (parallel [(const_int 0) (const_int 1)]))))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (vec_select:V2SI + (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 0) (const_int 1)])))] "TARGET_REALLY_IWMMXT" "wunpckelsh%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckel")] +) (define_insn "iwmmxt_wunpckelsw" - [(set (match_operand:DI 0 "register_operand" "=y") - (sign_extend:DI - (vec_select:SI (match_operand:V2SI 1 "register_operand" "y") - (parallel [(const_int 0)]))))] + [(set (match_operand:DI 0 "register_operand" "=y") + (vec_select:DI + (sign_extend:V2DI (match_operand:V2SI 1 "register_operand" "y")) + (parallel [(const_int 0)])))] "TARGET_REALLY_IWMMXT" "wunpckelsw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wunpckel")] +) ;; Shifts -(define_insn "rorv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y") - (match_operand:SI 2 "register_operand" "z")))] - "TARGET_REALLY_IWMMXT" - "wrorhg%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "rorv2si3" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y") - (match_operand:SI 2 "register_operand" "z")))] +(define_insn "ror3" + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (rotatert:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:SI 2 "imm_or_reg_operand" "z,i")))] "TARGET_REALLY_IWMMXT" - "wrorwg%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "rordi3" - [(set (match_operand:DI 0 "register_operand" "=y") - (rotatert:DI (match_operand:DI 1 "register_operand" "y") - (match_operand:SI 2 "register_operand" "z")))] - "TARGET_REALLY_IWMMXT" - "wrordg%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wrorg%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wror\", operands, true); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wror, wror")] +) (define_insn "ashr3_iwmmxt" - [(set (match_operand:VSHFT 0 "register_operand" "=y") - (ashiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y") - (match_operand:SI 2 "register_operand" "z")))] + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (ashiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:SI 2 "imm_or_reg_operand" "z,i")))] "TARGET_REALLY_IWMMXT" - "wsrag%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wsrag%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wsra\", operands, true); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wsra, wsra")] +) (define_insn "lshr3_iwmmxt" - [(set (match_operand:VSHFT 0 "register_operand" "=y") - (lshiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y") - (match_operand:SI 2 "register_operand" "z")))] + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (lshiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:SI 2 "imm_or_reg_operand" "z,i")))] "TARGET_REALLY_IWMMXT" - "wsrlg%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wsrlg%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wsrl\", operands, false); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wsrl, wsrl")] +) (define_insn "ashl3_iwmmxt" - [(set (match_operand:VSHFT 0 "register_operand" "=y") - (ashift:VSHFT (match_operand:VSHFT 1 "register_operand" "y") - (match_operand:SI 2 "register_operand" "z")))] - "TARGET_REALLY_IWMMXT" - "wsllg%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "rorv4hi3_di" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wrorh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "rorv2si3_di" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wrorw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "rordi3_di" - [(set (match_operand:DI 0 "register_operand" "=y") - (rotatert:DI (match_operand:DI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wrord%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "ashrv4hi3_di" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (ashift:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:SI 2 "imm_or_reg_operand" "z,i")))] "TARGET_REALLY_IWMMXT" - "wsrah%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "ashrv2si3_di" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wsraw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wsllg%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wsll\", operands, false); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wsll, wsll")] +) -(define_insn "ashrdi3_di" - [(set (match_operand:DI 0 "register_operand" "=y") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] +(define_insn "ror3_di" + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (rotatert:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:DI 2 "imm_or_reg_operand" "y,i")))] "TARGET_REALLY_IWMMXT" - "wsrad%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wror%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wror\", operands, true); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wror, wror")] +) -(define_insn "lshrv4hi3_di" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] +(define_insn "ashr3_di" + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (ashiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:DI 2 "imm_or_reg_operand" "y,i")))] "TARGET_REALLY_IWMMXT" - "wsrlh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wsra%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wsra\", operands, true); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wsra, wsra")] +) -(define_insn "lshrv2si3_di" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] +(define_insn "lshr3_di" + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (lshiftrt:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:DI 2 "register_operand" "y,i")))] "TARGET_REALLY_IWMMXT" - "wsrlw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wsrl%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wsrl\", operands, false); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wsrl, wsrl")] +) -(define_insn "lshrdi3_di" - [(set (match_operand:DI 0 "register_operand" "=y") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wsrld%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "ashlv4hi3_di" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (ashift:V4HI (match_operand:V4HI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wsllh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "ashlv2si3_di" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (ashift:V2SI (match_operand:V2SI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] - "TARGET_REALLY_IWMMXT" - "wsllw%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "ashldi3_di" - [(set (match_operand:DI 0 "register_operand" "=y") - (ashift:DI (match_operand:DI 1 "register_operand" "y") - (match_operand:DI 2 "register_operand" "y")))] +(define_insn "ashl3_di" + [(set (match_operand:VSHFT 0 "register_operand" "=y,y") + (ashift:VSHFT (match_operand:VSHFT 1 "register_operand" "y,y") + (match_operand:DI 2 "imm_or_reg_operand" "y,i")))] "TARGET_REALLY_IWMMXT" - "wslld%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "* + switch (which_alternative) + { + case 0: + return \"wsll%?\\t%0, %1, %2\"; + case 1: + return arm_output_iwmmxt_shift_immediate (\"wsll\", operands, false); + default: + gcc_unreachable (); + } + " + [(set_attr "predicable" "yes") + (set_attr "arch" "*, iwmmxt2") + (set_attr "wtype" "wsll, wsll")] +) (define_insn "iwmmxt_wmadds" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDS))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (plus:V2SI + (mult:V2SI + (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 1) (const_int 3)])) + (vec_select:V2SI (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")) + (parallel [(const_int 1) (const_int 3)]))) + (mult:V2SI + (vec_select:V2SI (sign_extend:V4SI (match_dup 1)) + (parallel [(const_int 0) (const_int 2)])) + (vec_select:V2SI (sign_extend:V4SI (match_dup 2)) + (parallel [(const_int 0) (const_int 2)])))))] "TARGET_REALLY_IWMMXT" "wmadds%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmadd")] +) (define_insn "iwmmxt_wmaddu" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDU))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (plus:V2SI + (mult:V2SI + (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y")) + (parallel [(const_int 1) (const_int 3)])) + (vec_select:V2SI (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")) + (parallel [(const_int 1) (const_int 3)]))) + (mult:V2SI + (vec_select:V2SI (zero_extend:V4SI (match_dup 1)) + (parallel [(const_int 0) (const_int 2)])) + (vec_select:V2SI (zero_extend:V4SI (match_dup 2)) + (parallel [(const_int 0) (const_int 2)])))))] "TARGET_REALLY_IWMMXT" "wmaddu%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wmadd")] +) (define_insn "iwmmxt_tmia" - [(set (match_operand:DI 0 "register_operand" "=y") - (plus:DI (match_operand:DI 1 "register_operand" "0") + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") (mult:DI (sign_extend:DI - (match_operand:SI 2 "register_operand" "r")) + (match_operand:SI 2 "register_operand" "r")) (sign_extend:DI - (match_operand:SI 3 "register_operand" "r")))))] + (match_operand:SI 3 "register_operand" "r")))))] "TARGET_REALLY_IWMMXT" "tmia%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmia")] +) (define_insn "iwmmxt_tmiaph" - [(set (match_operand:DI 0 "register_operand" "=y") - (plus:DI (match_operand:DI 1 "register_operand" "0") + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") (plus:DI - (mult:DI (sign_extend:DI - (truncate:HI (match_operand:SI 2 "register_operand" "r"))) - (sign_extend:DI - (truncate:HI (match_operand:SI 3 "register_operand" "r")))) - (mult:DI (sign_extend:DI - (truncate:HI (ashiftrt:SI (match_dup 2) (const_int 16)))) - (sign_extend:DI - (truncate:HI (ashiftrt:SI (match_dup 3) (const_int 16))))))))] + (mult:DI (sign_extend:DI + (truncate:HI (match_operand:SI 2 "register_operand" "r"))) + (sign_extend:DI + (truncate:HI (match_operand:SI 3 "register_operand" "r")))) + (mult:DI (sign_extend:DI + (truncate:HI (ashiftrt:SI (match_dup 2) (const_int 16)))) + (sign_extend:DI + (truncate:HI (ashiftrt:SI (match_dup 3) (const_int 16))))))))] "TARGET_REALLY_IWMMXT" "tmiaph%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmiaph")] +) (define_insn "iwmmxt_tmiabb" - [(set (match_operand:DI 0 "register_operand" "=y") - (plus:DI (match_operand:DI 1 "register_operand" "0") + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") (mult:DI (sign_extend:DI - (truncate:HI (match_operand:SI 2 "register_operand" "r"))) + (truncate:HI (match_operand:SI 2 "register_operand" "r"))) (sign_extend:DI - (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))] + (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))] "TARGET_REALLY_IWMMXT" "tmiabb%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmiaxy")] +) (define_insn "iwmmxt_tmiatb" - [(set (match_operand:DI 0 "register_operand" "=y") - (plus:DI (match_operand:DI 1 "register_operand" "0") + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") (mult:DI (sign_extend:DI - (truncate:HI (ashiftrt:SI - (match_operand:SI 2 "register_operand" "r") - (const_int 16)))) + (truncate:HI + (ashiftrt:SI + (match_operand:SI 2 "register_operand" "r") + (const_int 16)))) (sign_extend:DI - (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))] + (truncate:HI + (match_operand:SI 3 "register_operand" "r"))))))] "TARGET_REALLY_IWMMXT" "tmiatb%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmiaxy")] +) (define_insn "iwmmxt_tmiabt" - [(set (match_operand:DI 0 "register_operand" "=y") - (plus:DI (match_operand:DI 1 "register_operand" "0") + [(set (match_operand:DI 0 "register_operand" "=y") + (plus:DI (match_operand:DI 1 "register_operand" "0") (mult:DI (sign_extend:DI - (truncate:HI (match_operand:SI 2 "register_operand" "r"))) + (truncate:HI + (match_operand:SI 2 "register_operand" "r"))) (sign_extend:DI - (truncate:HI (ashiftrt:SI - (match_operand:SI 3 "register_operand" "r") - (const_int 16)))))))] + (truncate:HI + (ashiftrt:SI + (match_operand:SI 3 "register_operand" "r") + (const_int 16)))))))] "TARGET_REALLY_IWMMXT" "tmiabt%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmiaxy")] +) (define_insn "iwmmxt_tmiatt" [(set (match_operand:DI 0 "register_operand" "=y") (plus:DI (match_operand:DI 1 "register_operand" "0") (mult:DI (sign_extend:DI - (truncate:HI (ashiftrt:SI - (match_operand:SI 2 "register_operand" "r") - (const_int 16)))) + (truncate:HI + (ashiftrt:SI + (match_operand:SI 2 "register_operand" "r") + (const_int 16)))) (sign_extend:DI - (truncate:HI (ashiftrt:SI - (match_operand:SI 3 "register_operand" "r") - (const_int 16)))))))] + (truncate:HI + (ashiftrt:SI + (match_operand:SI 3 "register_operand" "r") + (const_int 16)))))))] "TARGET_REALLY_IWMMXT" "tmiatt%?\\t%0, %2, %3" - [(set_attr "predicable" "yes")]) - -(define_insn "iwmmxt_tbcstqi" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (vec_duplicate:V8QI (match_operand:QI 1 "register_operand" "r")))] - "TARGET_REALLY_IWMMXT" - "tbcstb%?\\t%0, %1" - [(set_attr "predicable" "yes")]) - -(define_insn "iwmmxt_tbcsthi" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (vec_duplicate:V4HI (match_operand:HI 1 "register_operand" "r")))] - "TARGET_REALLY_IWMMXT" - "tbcsth%?\\t%0, %1" - [(set_attr "predicable" "yes")]) - -(define_insn "iwmmxt_tbcstsi" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (vec_duplicate:V2SI (match_operand:SI 1 "register_operand" "r")))] - "TARGET_REALLY_IWMMXT" - "tbcstw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmiaxy")] +) (define_insn "iwmmxt_tmovmskb" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_TMOVMSK))] "TARGET_REALLY_IWMMXT" "tmovmskb%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmovmsk")] +) (define_insn "iwmmxt_tmovmskh" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_TMOVMSK))] "TARGET_REALLY_IWMMXT" "tmovmskh%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmovmsk")] +) (define_insn "iwmmxt_tmovmskw" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_TMOVMSK))] "TARGET_REALLY_IWMMXT" "tmovmskw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "tmovmsk")] +) (define_insn "iwmmxt_waccb" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_WACC))] "TARGET_REALLY_IWMMXT" "waccb%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wacc")] +) (define_insn "iwmmxt_wacch" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_WACC))] "TARGET_REALLY_IWMMXT" "wacch%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wacc")] +) (define_insn "iwmmxt_waccw" [(set (match_operand:DI 0 "register_operand" "=y") (unspec:DI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_WACC))] "TARGET_REALLY_IWMMXT" "waccw%?\\t%0, %1" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wacc")] +) + +;; use unspec here to prevent 8 * imm to be optimized by cse +(define_insn "iwmmxt_waligni" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (unspec:V8QI [(subreg:V8QI + (ashiftrt:TI + (subreg:TI (vec_concat:V16QI + (match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")) 0) + (mult:SI + (match_operand:SI 3 "immediate_operand" "i") + (const_int 8))) 0)] UNSPEC_WALIGNI))] + "TARGET_REALLY_IWMMXT" + "waligni%?\\t%0, %1, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "waligni")] +) -(define_insn "iwmmxt_walign" - [(set (match_operand:V8QI 0 "register_operand" "=y,y") +(define_insn "iwmmxt_walignr" + [(set (match_operand:V8QI 0 "register_operand" "=y") (subreg:V8QI (ashiftrt:TI - (subreg:TI (vec_concat:V16QI - (match_operand:V8QI 1 "register_operand" "y,y") - (match_operand:V8QI 2 "register_operand" "y,y")) 0) - (mult:SI - (match_operand:SI 3 "nonmemory_operand" "i,z") - (const_int 8))) 0))] + (subreg:TI (vec_concat:V16QI + (match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")) 0) + (mult:SI + (zero_extract:SI (match_operand:SI 3 "register_operand" "z") (const_int 3) (const_int 0)) + (const_int 8))) 0))] "TARGET_REALLY_IWMMXT" - "@ - waligni%?\\t%0, %1, %2, %3 - walignr%U3%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) - -(define_insn "iwmmxt_tmrc" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")] - VUNSPEC_TMRC))] - "TARGET_REALLY_IWMMXT" - "tmrc%?\\t%0, %w1" - [(set_attr "predicable" "yes")]) - -(define_insn "iwmmxt_tmcr" - [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") - (match_operand:SI 1 "register_operand" "r")] - VUNSPEC_TMCR)] + "walignr%U3%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "walignr")] +) + +(define_insn "iwmmxt_walignr0" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (subreg:V8QI (ashiftrt:TI + (subreg:TI (vec_concat:V16QI + (match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")) 0) + (mult:SI + (zero_extract:SI (reg:SI WCGR0) (const_int 3) (const_int 0)) + (const_int 8))) 0))] + "TARGET_REALLY_IWMMXT" + "walignr0%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "walignr")] +) + +(define_insn "iwmmxt_walignr1" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (subreg:V8QI (ashiftrt:TI + (subreg:TI (vec_concat:V16QI + (match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")) 0) + (mult:SI + (zero_extract:SI (reg:SI WCGR1) (const_int 3) (const_int 0)) + (const_int 8))) 0))] + "TARGET_REALLY_IWMMXT" + "walignr1%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "walignr")] +) + +(define_insn "iwmmxt_walignr2" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (subreg:V8QI (ashiftrt:TI + (subreg:TI (vec_concat:V16QI + (match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")) 0) + (mult:SI + (zero_extract:SI (reg:SI WCGR2) (const_int 3) (const_int 0)) + (const_int 8))) 0))] + "TARGET_REALLY_IWMMXT" + "walignr2%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "walignr")] +) + +(define_insn "iwmmxt_walignr3" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (subreg:V8QI (ashiftrt:TI + (subreg:TI (vec_concat:V16QI + (match_operand:V8QI 1 "register_operand" "y") + (match_operand:V8QI 2 "register_operand" "y")) 0) + (mult:SI + (zero_extract:SI (reg:SI WCGR3) (const_int 3) (const_int 0)) + (const_int 8))) 0))] "TARGET_REALLY_IWMMXT" - "tmcr%?\\t%w0, %1" - [(set_attr "predicable" "yes")]) + "walignr3%?\\t%0, %1, %2" + [(set_attr "predicable" "yes") + (set_attr "wtype" "walignr")] +) (define_insn "iwmmxt_wsadb" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSAD))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [ + (match_operand:V2SI 1 "register_operand" "0") + (match_operand:V8QI 2 "register_operand" "y") + (match_operand:V8QI 3 "register_operand" "y")] UNSPEC_WSAD))] "TARGET_REALLY_IWMMXT" - "wsadb%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "wsadb%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsad")] +) (define_insn "iwmmxt_wsadh" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y") - (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSAD))] + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [ + (match_operand:V2SI 1 "register_operand" "0") + (match_operand:V4HI 2 "register_operand" "y") + (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WSAD))] "TARGET_REALLY_IWMMXT" - "wsadh%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + "wsadh%?\\t%0, %2, %3" + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsad")] +) (define_insn "iwmmxt_wsadbz" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V8QI 1 "register_operand" "y") (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSADZ))] "TARGET_REALLY_IWMMXT" "wsadbz%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsad")] +) (define_insn "iwmmxt_wsadhz" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y") + [(set (match_operand:V2SI 0 "register_operand" "=y") + (unspec:V2SI [(match_operand:V4HI 1 "register_operand" "y") (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSADZ))] "TARGET_REALLY_IWMMXT" "wsadhz%?\\t%0, %1, %2" - [(set_attr "predicable" "yes")]) + [(set_attr "predicable" "yes") + (set_attr "wtype" "wsad")] +) +(include "iwmmxt2.md") diff -ruN gcc/config/arm/marvell-f-iwmmxt.md gcc/config/arm/marvell-f-iwmmxt.md --- gcc/config/arm/marvell-f-iwmmxt.md 1969-12-31 16:00:00.000000000 -0800 +++ gcc/config/arm/marvell-f-iwmmxt.md 2013-01-27 20:14:06.009979280 -0800 @@ -0,0 +1,179 @@ +;; Marvell WMMX2 pipeline description +;; Copyright (C) 2011, 2012 Free Software Foundation, Inc. +;; Written by Marvell, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + + +(define_automaton "marvell_f_iwmmxt") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pipelines +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; This is a 7-stage pipelines: +;; +;; MD | MI | ME1 | ME2 | ME3 | ME4 | MW +;; +;; There are various bypasses modelled to a greater or lesser extent. +;; +;; Latencies in this file correspond to the number of cycles after +;; the issue stage that it takes for the result of the instruction to +;; be computed, or for its side-effects to occur. + +(define_cpu_unit "mf_iwmmxt_MD" "marvell_f_iwmmxt") +(define_cpu_unit "mf_iwmmxt_MI" "marvell_f_iwmmxt") +(define_cpu_unit "mf_iwmmxt_ME1" "marvell_f_iwmmxt") +(define_cpu_unit "mf_iwmmxt_ME2" "marvell_f_iwmmxt") +(define_cpu_unit "mf_iwmmxt_ME3" "marvell_f_iwmmxt") +(define_cpu_unit "mf_iwmmxt_ME4" "marvell_f_iwmmxt") +(define_cpu_unit "mf_iwmmxt_MW" "marvell_f_iwmmxt") + +(define_reservation "mf_iwmmxt_ME" + "mf_iwmmxt_ME1,mf_iwmmxt_ME2,mf_iwmmxt_ME3,mf_iwmmxt_ME4" +) + +(define_reservation "mf_iwmmxt_pipeline" + "mf_iwmmxt_MD, mf_iwmmxt_MI, mf_iwmmxt_ME, mf_iwmmxt_MW" +) + +;; An attribute to indicate whether our reservations are applicable. +(define_attr "marvell_f_iwmmxt" "yes,no" + (const (if_then_else (symbol_ref "arm_arch_iwmmxt") + (const_string "yes") (const_string "no")))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; instruction classes +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; An attribute appended to instructions for classification + +(define_attr "wmmxt_shift" "yes,no" + (if_then_else (eq_attr "wtype" "wror, wsll, wsra, wsrl") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_pack" "yes,no" + (if_then_else (eq_attr "wtype" "waligni, walignr, wmerge, wpack, wshufh, wunpckeh, wunpckih, wunpckel, wunpckil") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_mult_c1" "yes,no" + (if_then_else (eq_attr "wtype" "wmac, wmadd, wmiaxy, wmiawxy, wmulw, wqmiaxy, wqmulwm") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_mult_c2" "yes,no" + (if_then_else (eq_attr "wtype" "wmul, wqmulm") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_alu_c1" "yes,no" + (if_then_else (eq_attr "wtype" "wabs, wabsdiff, wand, wandn, wmov, wor, wxor") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_alu_c2" "yes,no" + (if_then_else (eq_attr "wtype" "wacc, wadd, waddsubhx, wavg2, wavg4, wcmpeq, wcmpgt, wmax, wmin, wsub, waddbhus, wsubaddhx") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_alu_c3" "yes,no" + (if_then_else (eq_attr "wtype" "wsad") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_transfer_c1" "yes,no" + (if_then_else (eq_attr "wtype" "tbcst, tinsr, tmcr, tmcrr") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_transfer_c2" "yes,no" + (if_then_else (eq_attr "wtype" "textrm, tmovmsk, tmrc, tmrrc") + (const_string "yes") (const_string "no")) +) + +(define_attr "wmmxt_transfer_c3" "yes,no" + (if_then_else (eq_attr "wtype" "tmia, tmiaph, tmiaxy") + (const_string "yes") (const_string "no")) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main description +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn_reservation "marvell_f_iwmmxt_alu_c1" 1 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_alu_c1" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_pack" 1 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_pack" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_shift" 1 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_shift" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_transfer_c1" 1 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_transfer_c1" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_transfer_c2" 5 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_transfer_c2" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_alu_c2" 2 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_alu_c2" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_alu_c3" 3 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_alu_c3" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_transfer_c3" 4 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_transfer_c3" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_mult_c1" 4 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_mult_c1" "yes")) + "mf_iwmmxt_pipeline") + +;There is a forwarding path from ME3 stage +(define_insn_reservation "marvell_f_iwmmxt_mult_c2" 3 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wmmxt_mult_c2" "yes")) + "mf_iwmmxt_pipeline") + +(define_insn_reservation "marvell_f_iwmmxt_wstr" 0 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wtype" "wstr")) + "mf_iwmmxt_pipeline") + +;There is a forwarding path from MW stage +(define_insn_reservation "marvell_f_iwmmxt_wldr" 5 + (and (eq_attr "marvell_f_iwmmxt" "yes") + (eq_attr "wtype" "wldr")) + "mf_iwmmxt_pipeline") diff -ruN gcc/config/arm/mmintrin.h gcc/config/arm/mmintrin.h --- gcc/config/arm/mmintrin.h 2009-04-09 08:00:19.000000000 -0700 +++ gcc/config/arm/mmintrin.h 2013-01-27 20:18:43.110961865 -0800 @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2009, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -24,16 +24,26 @@ #ifndef _MMINTRIN_H_INCLUDED #define _MMINTRIN_H_INCLUDED +#ifndef __IWMMXT__ +#error mmintrin.h included without enabling WMMX/WMMX2 instructions (e.g. -march=iwmmxt or -march=iwmmxt2) +#endif + + +#if defined __cplusplus +extern "C" { +/* Intrinsics use C name-mangling. */ +#endif /* __cplusplus */ + /* The data type intended for user use. */ typedef unsigned long long __m64, __int64; /* Internal data types for implementing the intrinsics. */ typedef int __v2si __attribute__ ((vector_size (8))); typedef short __v4hi __attribute__ ((vector_size (8))); -typedef char __v8qi __attribute__ ((vector_size (8))); +typedef signed char __v8qi __attribute__ ((vector_size (8))); /* "Convert" __m64 and __int64 into each other. */ -static __inline __m64 +static __inline __m64 _mm_cvtsi64_m64 (__int64 __i) { return __i; @@ -54,7 +64,7 @@ static __inline __int64 _mm_cvtsi32_si64 (int __i) { - return __i; + return (__i & 0xffffffff); } /* Pack the four 16-bit values from M1 into the lower four 8-bit values of @@ -603,7 +613,7 @@ static __inline __m64 _mm_andnot_si64 (__m64 __m1, __m64 __m2) { - return __builtin_arm_wandn (__m1, __m2); + return __builtin_arm_wandn (__m2, __m1); } /* Bit-wise inclusive OR the 64-bit values in M1 and M2. */ @@ -935,7 +945,13 @@ static __inline __m64 _mm_sad_pu8 (__m64 __A, __m64 __B) { - return (__m64) __builtin_arm_wsadb ((__v8qi)__A, (__v8qi)__B); + return (__m64) __builtin_arm_wsadbz ((__v8qi)__A, (__v8qi)__B); +} + +static __inline __m64 +_mm_sada_pu8 (__m64 __A, __m64 __B, __m64 __C) +{ + return (__m64) __builtin_arm_wsadb ((__v2si)__A, (__v8qi)__B, (__v8qi)__C); } /* Compute the sum of the absolute differences of the unsigned 16-bit @@ -944,9 +960,16 @@ static __inline __m64 _mm_sad_pu16 (__m64 __A, __m64 __B) { - return (__m64) __builtin_arm_wsadh ((__v4hi)__A, (__v4hi)__B); + return (__m64) __builtin_arm_wsadhz ((__v4hi)__A, (__v4hi)__B); +} + +static __inline __m64 +_mm_sada_pu16 (__m64 __A, __m64 __B, __m64 __C) +{ + return (__m64) __builtin_arm_wsadh ((__v2si)__A, (__v4hi)__B, (__v4hi)__C); } + /* Compute the sum of the absolute differences of the unsigned 8-bit values in A and B. Return the value in the lower 16-bit word; the upper words are cleared. */ @@ -965,11 +988,8 @@ return (__m64) __builtin_arm_wsadhz ((__v4hi)__A, (__v4hi)__B); } -static __inline __m64 -_mm_align_si64 (__m64 __A, __m64 __B, int __C) -{ - return (__m64) __builtin_arm_walign ((__v8qi)__A, (__v8qi)__B, __C); -} +#define _mm_align_si64(__A,__B, N) \ + (__m64) __builtin_arm_walign ((__v8qi) (__A),(__v8qi) (__B), (N)) /* Creates a 64-bit zero. */ static __inline __m64 @@ -987,42 +1007,76 @@ { switch (__regno) { - case 0: __builtin_arm_setwcx (__value, 0); break; - case 1: __builtin_arm_setwcx (__value, 1); break; - case 2: __builtin_arm_setwcx (__value, 2); break; - case 3: __builtin_arm_setwcx (__value, 3); break; - case 8: __builtin_arm_setwcx (__value, 8); break; - case 9: __builtin_arm_setwcx (__value, 9); break; - case 10: __builtin_arm_setwcx (__value, 10); break; - case 11: __builtin_arm_setwcx (__value, 11); break; - default: break; + case 0: + __asm __volatile ("tmcr wcid, %0" :: "r"(__value)); + break; + case 1: + __asm __volatile ("tmcr wcon, %0" :: "r"(__value)); + break; + case 2: + __asm __volatile ("tmcr wcssf, %0" :: "r"(__value)); + break; + case 3: + __asm __volatile ("tmcr wcasf, %0" :: "r"(__value)); + break; + case 8: + __builtin_arm_setwcgr0 (__value); + break; + case 9: + __builtin_arm_setwcgr1 (__value); + break; + case 10: + __builtin_arm_setwcgr2 (__value); + break; + case 11: + __builtin_arm_setwcgr3 (__value); + break; + default: + break; } } static __inline int _mm_getwcx (const int __regno) { + int __value; switch (__regno) { - case 0: return __builtin_arm_getwcx (0); - case 1: return __builtin_arm_getwcx (1); - case 2: return __builtin_arm_getwcx (2); - case 3: return __builtin_arm_getwcx (3); - case 8: return __builtin_arm_getwcx (8); - case 9: return __builtin_arm_getwcx (9); - case 10: return __builtin_arm_getwcx (10); - case 11: return __builtin_arm_getwcx (11); - default: return 0; + case 0: + __asm __volatile ("tmrc %0, wcid" : "=r"(__value)); + break; + case 1: + __asm __volatile ("tmrc %0, wcon" : "=r"(__value)); + break; + case 2: + __asm __volatile ("tmrc %0, wcssf" : "=r"(__value)); + break; + case 3: + __asm __volatile ("tmrc %0, wcasf" : "=r"(__value)); + break; + case 8: + return __builtin_arm_getwcgr0 (); + case 9: + return __builtin_arm_getwcgr1 (); + case 10: + return __builtin_arm_getwcgr2 (); + case 11: + return __builtin_arm_getwcgr3 (); + default: + break; } + return __value; } /* Creates a vector of two 32-bit values; I0 is least significant. */ static __inline __m64 _mm_set_pi32 (int __i1, int __i0) { - union { + union + { __m64 __q; - struct { + struct + { unsigned int __i0; unsigned int __i1; } __s; @@ -1038,10 +1092,10 @@ static __inline __m64 _mm_set_pi16 (short __w3, short __w2, short __w1, short __w0) { - unsigned int __i1 = (unsigned short)__w3 << 16 | (unsigned short)__w2; - unsigned int __i0 = (unsigned short)__w1 << 16 | (unsigned short)__w0; + unsigned int __i1 = (unsigned short) __w3 << 16 | (unsigned short) __w2; + unsigned int __i0 = (unsigned short) __w1 << 16 | (unsigned short) __w0; + return _mm_set_pi32 (__i1, __i0); - } /* Creates a vector of eight 8-bit values; B0 is least significant. */ @@ -1108,11 +1162,526 @@ return _mm_set1_pi32 (__i); } -/* Convert an integer to a __m64 object. */ +#ifdef __IWMMXT2__ +static __inline __m64 +_mm_abs_pi8 (__m64 m1) +{ + return (__m64) __builtin_arm_wabsb ((__v8qi)m1); +} + +static __inline __m64 +_mm_abs_pi16 (__m64 m1) +{ + return (__m64) __builtin_arm_wabsh ((__v4hi)m1); + +} + +static __inline __m64 +_mm_abs_pi32 (__m64 m1) +{ + return (__m64) __builtin_arm_wabsw ((__v2si)m1); + +} + +static __inline __m64 +_mm_addsubhx_pi16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_waddsubhx ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_absdiff_pu8 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wabsdiffb ((__v8qi)a, (__v8qi)b); +} + +static __inline __m64 +_mm_absdiff_pu16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wabsdiffh ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_absdiff_pu32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wabsdiffw ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_addc_pu16 (__m64 a, __m64 b) +{ + __m64 result; + __asm__ __volatile__ ("waddhc %0, %1, %2" : "=y" (result) : "y" (a), "y" (b)); + return result; +} + +static __inline __m64 +_mm_addc_pu32 (__m64 a, __m64 b) +{ + __m64 result; + __asm__ __volatile__ ("waddwc %0, %1, %2" : "=y" (result) : "y" (a), "y" (b)); + return result; +} + +static __inline __m64 +_mm_avg4_pu8 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wavg4 ((__v8qi)a, (__v8qi)b); +} + +static __inline __m64 +_mm_avg4r_pu8 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wavg4r ((__v8qi)a, (__v8qi)b); +} + +static __inline __m64 +_mm_maddx_pi16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmaddsx ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_maddx_pu16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmaddux ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_msub_pi16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmaddsn ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_msub_pu16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmaddun ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_mulhi_pi32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulwsm ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_mulhi_pu32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulwum ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_mulhir_pi16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulsmr ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_mulhir_pi32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulwsmr ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_mulhir_pu16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulumr ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_mulhir_pu32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulwumr ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_mullo_pi32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wmulwl ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_qmulm_pi16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wqmulm ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_qmulm_pi32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wqmulwm ((__v2si)a, (__v2si)b); +} + static __inline __m64 -_m_from_int (int __a) +_mm_qmulmr_pi16 (__m64 a, __m64 b) { - return (__m64)__a; + return (__m64) __builtin_arm_wqmulmr ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_qmulmr_pi32 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wqmulwmr ((__v2si)a, (__v2si)b); +} + +static __inline __m64 +_mm_subaddhx_pi16 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_wsubaddhx ((__v4hi)a, (__v4hi)b); +} + +static __inline __m64 +_mm_addbhusl_pu8 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_waddbhusl ((__v4hi)a, (__v8qi)b); +} + +static __inline __m64 +_mm_addbhusm_pu8 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_waddbhusm ((__v4hi)a, (__v8qi)b); +} + +#define _mm_qmiabb_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiabb ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiabbn_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiabbn ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiabt_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiabt ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiabtn_pi32(acc, m1, m2) \ + ({\ + __m64 _acc=acc;\ + __m64 _m1=m1;\ + __m64 _m2=m2;\ + _acc = (__m64) __builtin_arm_wqmiabtn ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiatb_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiatb ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiatbn_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiatbn ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiatt_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiatt ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_qmiattn_pi32(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wqmiattn ((__v2si)_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiabb_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiabb (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiabbn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiabbn (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiabt_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiabt (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiabtn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiabtn (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiatb_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiatb (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiatbn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiatbn (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiatt_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiatt (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiattn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiattn (_acc, (__v4hi)_m1, (__v4hi)_m2);\ + _acc;\ + }) + +#define _mm_wmiawbb_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawbb (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawbbn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawbbn (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawbt_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawbt (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawbtn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawbtn (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawtb_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawtb (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawtbn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawtbn (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawtt_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawtt (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +#define _mm_wmiawttn_si64(acc, m1, m2) \ + ({\ + __m64 _acc = acc;\ + __m64 _m1 = m1;\ + __m64 _m2 = m2;\ + _acc = (__m64) __builtin_arm_wmiawttn (_acc, (__v2si)_m1, (__v2si)_m2);\ + _acc;\ + }) + +/* The third arguments should be an immediate. */ +#define _mm_merge_si64(a, b, n) \ + ({\ + __m64 result;\ + result = (__m64) __builtin_arm_wmerge ((__m64) (a), (__m64) (b), (n));\ + result;\ + }) +#endif /* __IWMMXT2__ */ + +static __inline __m64 +_mm_alignr0_si64 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_walignr0 ((__v8qi) a, (__v8qi) b); +} + +static __inline __m64 +_mm_alignr1_si64 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_walignr1 ((__v8qi) a, (__v8qi) b); +} + +static __inline __m64 +_mm_alignr2_si64 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_walignr2 ((__v8qi) a, (__v8qi) b); +} + +static __inline __m64 +_mm_alignr3_si64 (__m64 a, __m64 b) +{ + return (__m64) __builtin_arm_walignr3 ((__v8qi) a, (__v8qi) b); +} + +static __inline void +_mm_tandcb () +{ + __asm __volatile ("tandcb r15"); +} + +static __inline void +_mm_tandch () +{ + __asm __volatile ("tandch r15"); +} + +static __inline void +_mm_tandcw () +{ + __asm __volatile ("tandcw r15"); +} + +#define _mm_textrcb(n) \ + ({\ + __asm__ __volatile__ (\ + "textrcb r15, %0" : : "i" (n));\ + }) + +#define _mm_textrch(n) \ + ({\ + __asm__ __volatile__ (\ + "textrch r15, %0" : : "i" (n));\ + }) + +#define _mm_textrcw(n) \ + ({\ + __asm__ __volatile__ (\ + "textrcw r15, %0" : : "i" (n));\ + }) + +static __inline void +_mm_torcb () +{ + __asm __volatile ("torcb r15"); +} + +static __inline void +_mm_torch () +{ + __asm __volatile ("torch r15"); +} + +static __inline void +_mm_torcw () +{ + __asm __volatile ("torcw r15"); +} + +#ifdef __IWMMXT2__ +static __inline void +_mm_torvscb () +{ + __asm __volatile ("torvscb r15"); +} + +static __inline void +_mm_torvsch () +{ + __asm __volatile ("torvsch r15"); +} + +static __inline void +_mm_torvscw () +{ + __asm __volatile ("torvscw r15"); +} +#endif /* __IWMMXT2__ */ + +static __inline __m64 +_mm_tbcst_pi8 (int value) +{ + return (__m64) __builtin_arm_tbcstb ((signed char) value); +} + +static __inline __m64 +_mm_tbcst_pi16 (int value) +{ + return (__m64) __builtin_arm_tbcsth ((short) value); +} + +static __inline __m64 +_mm_tbcst_pi32 (int value) +{ + return (__m64) __builtin_arm_tbcstw (value); } #define _m_packsswb _mm_packs_pi16 @@ -1250,5 +1819,11 @@ #define _m_paligniq _mm_align_si64 #define _m_cvt_si2pi _mm_cvtsi64_m64 #define _m_cvt_pi2si _mm_cvtm64_si64 +#define _m_from_int _mm_cvtsi32_si64 +#define _m_to_int _mm_cvtsi64_si32 + +#if defined __cplusplus +}; /* End "C" */ +#endif /* __cplusplus */ #endif /* _MMINTRIN_H_INCLUDED */ diff -ruN gcc/config/arm/predicates.md gcc/config/arm/predicates.md --- gcc/config/arm/predicates.md 2012-01-09 20:14:09.000000000 -0800 +++ gcc/config/arm/predicates.md 2013-01-27 20:14:06.010979280 -0800 @@ -1,5 +1,5 @@ ;; Predicate definitions for ARM and Thumb -;; Copyright (C) 2004, 2007, 2008, 2010 Free Software Foundation, Inc. +;; Copyright (C) 2004, 2007, 2008, 2010, 2012 Free Software Foundation, Inc. ;; Contributed by ARM Ltd. ;; This file is part of GCC. @@ -619,6 +619,11 @@ (and (match_code "const_int") (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) +;; iWMMXt predicates + +(define_predicate "imm_or_reg_operand" + (ior (match_operand 0 "immediate_operand") + (match_operand 0 "register_operand"))) ;; Neon predicates diff -ruN gcc/config/arm/t-arm gcc/config/arm/t-arm --- gcc/config/arm/t-arm 2011-11-30 05:51:35.000000000 -0800 +++ gcc/config/arm/t-arm 2013-01-27 20:14:06.010979280 -0800 @@ -1,6 +1,6 @@ # Rules common to all arm targets # -# Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011 +# Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 # Free Software Foundation, Inc. # # This file is part of GCC. @@ -49,7 +49,9 @@ $(srcdir)/config/arm/fpa.md \ $(srcdir)/config/arm/iterators.md \ $(srcdir)/config/arm/iwmmxt.md \ + $(srcdir)/config/arm/iwmmxt2.md \ $(srcdir)/config/arm/ldmstm.md \ + $(srcdir)/config/arm/marvell-f-iwmmxt.md \ $(srcdir)/config/arm/neon.md \ $(srcdir)/config/arm/predicates.md \ $(srcdir)/config/arm/sync.md \