arm.c (FL_IWMMXT2): New define.

* config/arm/arm.c (FL_IWMMXT2): New define.
	(arm_arch_iwmmxt2): New variable.
	(arm_option_override): Enable use of iWMMXt with VFP.
	Disable use of iWMMXt with NEON. Disable use of iWMMXt under
	Thumb mode. Set arm_arch_iwmmxt2.
	(arm_expand_binop_builtin): Accept VOIDmode op.
	(enum arm_builtins): Revise built-in fcode.
	(IWMMXT2_BUILTIN): New define.
	(IWMMXT2_BUILTIN2): Likewise.
	(iwmmx2_mbuiltin): Likewise.
	(builtin_description bdesc_2arg): Revise built in declaration.
	(builtin_description bdesc_1arg): Likewise.
	(arm_init_iwmmxt_builtins): Revise built in initialization.
	(arm_expand_builtin): Revise built in expansion.
	(arm_output_iwmmxt_shift_immediate): New function.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
	(arm_output_iwmmxt_tinsr): Likewise.
	* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
	(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
	(rorv4hi3, rorv2si3, rordi3): Likewise.
	(rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
	(ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
	(lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
	(ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
	(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
	(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
	(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
	(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
	(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
	(ror<mode>3, ror<mode>3_di): Likewise.
	(ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
	(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
	(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
	(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
	(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
	(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
	(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
	(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
	(All instruction patterns): Add wtype attribute.
	(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
	(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
	(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
	(ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt): Likewise.
	(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
	(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
	(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
	(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
	(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
	(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
	(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
	(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
	(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
	(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
	(iwmmxt2.md): Include.
	* config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __IWMMXT2__.
	(TARGET_IWMMXT2): New define.
	(TARGET_REALLY_IWMMXT2): Likewise.
	(arm_arch_iwmmxt2): Declare.
	* config/arm/mmintrin.h: Use __IWMMXT__ to enable iWMMXt intrinsics.
	Use __IWMMXT2__ to enable iWMMXt2 intrinsics.
	Use C name-mangling for intrinsics.
	(__v8qi): Redefine.
	(_mm_cvtsi32_si64, _mm_andnot_si64, _mm_sad_pu8): Revise.
	(_mm_sad_pu16, _mm_align_si64, _mm_setwcx, _mm_getwcx): Likewise.
	(_m_from_int): Likewise.
	(_mm_sada_pu8, _mm_sada_pu16): New intrinsic.
	(_mm_alignr0_si64, _mm_alignr1_si64, _mm_alignr2_si64): Likewise.
	(_mm_alignr3_si64, _mm_tandcb, _mm_tandch, _mm_tandcw): Likewise.
	(_mm_textrcb, _mm_textrch, _mm_textrcw, _mm_torcb): Likewise.
	(_mm_torch, _mm_torcw, _mm_tbcst_pi8, _mm_tbcst_pi16): Likewise.
	(_mm_tbcst_pi32): Likewise.
	(_mm_abs_pi8, _mm_abs_pi16, _mm_abs_pi32): New iWMMXt2 intrinsic.
	(_mm_addsubhx_pi16, _mm_absdiff_pu8, _mm_absdiff_pu16): Likewise.
	(_mm_absdiff_pu32, _mm_addc_pu16, _mm_addc_pu32): Likewise.
	(_mm_avg4_pu8, _mm_avg4r_pu8, _mm_maddx_pi16, _mm_maddx_pu16): Likewise.
	(_mm_msub_pi16, _mm_msub_pu16, _mm_mulhi_pi32): Likewise.
	(_mm_mulhi_pu32, _mm_mulhir_pi16, _mm_mulhir_pi32): Likewise.
	(_mm_mulhir_pu16, _mm_mulhir_pu32, _mm_mullo_pi32): Likewise.
	(_mm_qmulm_pi16, _mm_qmulm_pi32, _mm_qmulmr_pi16): Likewise.
	(_mm_qmulmr_pi32, _mm_subaddhx_pi16, _mm_addbhusl_pu8): Likewise.
	(_mm_addbhusm_pu8, _mm_qmiabb_pi32, _mm_qmiabbn_pi32): Likewise.
	(_mm_qmiabt_pi32, _mm_qmiabtn_pi32, _mm_qmiatb_pi32): Likewise.
	(_mm_qmiatbn_pi32, _mm_qmiatt_pi32, _mm_qmiattn_pi32): Likewise.
	(_mm_wmiabb_si64, _mm_wmiabbn_si64, _mm_wmiabt_si64): Likewise.
	(_mm_wmiabtn_si64, _mm_wmiatb_si64, _mm_wmiatbn_si64): Likewise.
	(_mm_wmiatt_si64, _mm_wmiattn_si64, _mm_wmiawbb_si64): Likewise.
	(_mm_wmiawbbn_si64, _mm_wmiawbt_si64, _mm_wmiawbtn_si64): Likewise.
	(_mm_wmiawtb_si64, _mm_wmiawtbn_si64, _mm_wmiawtt_si64): Likewise.
	(_mm_wmiawttn_si64, _mm_merge_si64): Likewise.
	(_mm_torvscb, _mm_torvsch, _mm_torvscw): Likewise.
	(_m_to_int): New define.
	* config/arm/arm-cores.def (iwmmxt2): Add FL_IWMMXT2.
	* config/arm/arm-arches.def (iwmmxt2): Likewise.
	* config/arm/t-arm (MD_INCLUDES): Add marvell-f-iwmmxt.md and
	iwmmxt2.md.
	* config/arm/arm.md (marvell-f-iwmmxt.md): Include.
	(arch): Add "iwmmxt2".
	(arch_enabled): Handle "iwmmxt2".
	(wtype): New attribute.
	(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
	(UNSPEC_WALIGNI): New unspec.
	* config/arm/predicates.md (imm_or_reg_operand): New predicate.
	* config/arm/iterators.md (VMMX2): New mode_iterator.
	* config/arm/marvell-f-iwmmxt.md: New file.
	* config/arm/iwmmxt2.md: New file.

From-SVN: r188497
This commit is contained in:
Xinyu Qi 2012-06-13 07:28:51 +00:00 committed by Nick Clifton
parent 73b5b93a59
commit 8fd0351502
14 changed files with 3621 additions and 771 deletions

View File

@ -1,3 +1,112 @@
2012-06-13 Xinyu Qi <xyqi@marvell.com>
* config/arm/arm.c (FL_IWMMXT2): New define.
(arm_arch_iwmmxt2): New variable.
(arm_option_override): Enable use of iWMMXt with VFP.
Disable use of iWMMXt with NEON. Disable use of iWMMXt under
Thumb mode. Set arm_arch_iwmmxt2.
(arm_expand_binop_builtin): Accept VOIDmode op.
(enum arm_builtins): Revise built-in fcode.
(IWMMXT2_BUILTIN): New define.
(IWMMXT2_BUILTIN2): Likewise.
(iwmmx2_mbuiltin): Likewise.
(builtin_description bdesc_2arg): Revise built in declaration.
(builtin_description bdesc_1arg): Likewise.
(arm_init_iwmmxt_builtins): Revise built in initialization.
(arm_expand_builtin): Revise built in expansion.
(arm_output_iwmmxt_shift_immediate): New function.
(arm_output_iwmmxt_tinsr): Likewise.
* config/arm/arm-protos.h (arm_output_iwmmxt_shift_immediate): Declare.
(arm_output_iwmmxt_tinsr): Likewise.
* config/arm/iwmmxt.md (WCGR0, WCGR1, WCGR2, WCGR3): New constant.
(iwmmxt_psadbw, iwmmxt_walign, iwmmxt_tmrc, iwmmxt_tmcr): Delete.
(rorv4hi3, rorv2si3, rordi3): Likewise.
(rorv4hi3_di, rorv2si3_di, rordi3_di): Likewise.
(ashrv4hi3_di, ashrv2si3_di, ashrdi3_di): Likewise.
(lshrv4hi3_di, lshrv2si3_di, lshrdi3_di): Likewise.
(ashlv4hi3_di, ashlv2si3_di, ashldi3_di): Likewise.
(iwmmxt_tbcstqi, iwmmxt_tbcsthi, iwmmxt_tbcstsi): Likewise
(*iwmmxt_clrv8qi, *iwmmxt_clrv4hi, *iwmmxt_clrv2si): Likewise.
(tbcstv8qi, tbcstv4hi, tbsctv2si): New pattern.
(iwmmxt_clrv8qi, iwmmxt_clrv4hi, iwmmxt_clrv2si): Likewise.
(*and<mode>3_iwmmxt, *ior<mode>3_iwmmxt, *xor<mode>3_iwmmxt): Likewise.
(ror<mode>3, ror<mode>3_di): Likewise.
(ashr<mode>3_di, lshr<mode>3_di, ashl<mode>3_di): Likewise.
(ashli<mode>3_iwmmxt, iwmmxt_waligni, iwmmxt_walignr): Likewise.
(iwmmxt_walignr0, iwmmxt_walignr1): Likewise.
(iwmmxt_walignr2, iwmmxt_walignr3): Likewise.
(iwmmxt_setwcgr0, iwmmxt_setwcgr1): Likewise.
(iwmmxt_setwcgr2, iwmmxt_setwcgr3): Likewise.
(iwmmxt_getwcgr0, iwmmxt_getwcgr1): Likewise.
(iwmmxt_getwcgr2, iwmmxt_getwcgr3): Likewise.
(All instruction patterns): Add wtype attribute.
(*iwmmxt_arm_movdi, *iwmmxt_movsi_insn): iWMMXt coexist with vfp.
(iwmmxt_uavgrndv8qi3, iwmmxt_uavgrndv4hi3): Revise the pattern.
(iwmmxt_uavgv8qi3, iwmmxt_uavgv4hi3): Likewise.
(ashr<mode>3_iwmmxt, ashl<mode>3_iwmmxt, lshr<mode>3_iwmmxt): Likewise.
(iwmmxt_tinsrb, iwmmxt_tinsrh, iwmmxt_tinsrw):Likewise.
(eqv8qi3, eqv4hi3, eqv2si3, gtuv8qi3): Likewise.
(gtuv4hi3, gtuv2si3, gtv8qi3, gtv4hi3, gtv2si3): Likewise.
(iwmmxt_wunpckihh, iwmmxt_wunpckihw, iwmmxt_wunpckilh): Likewise.
(iwmmxt_wunpckilw, iwmmxt_wunpckehub, iwmmxt_wunpckehuh): Likewise.
(iwmmxt_wunpckehuw, iwmmxt_wunpckehsb, iwmmxt_wunpckehsh): Likewise.
(iwmmxt_wunpckehsw, iwmmxt_wunpckelub, iwmmxt_wunpckeluh): Likewise.
(iwmmxt_wunpckeluw, iwmmxt_wunpckelsb, iwmmxt_wunpckelsh): Likewise.
(iwmmxt_wunpckelsw, iwmmxt_wmadds, iwmmxt_wmaddu): Likewise.
(iwmmxt_wsadb, iwmmxt_wsadh, iwmmxt_wsadbz, iwmmxt_wsadhz): Likewise.
(iwmmxt2.md): Include.
* config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __IWMMXT2__.
(TARGET_IWMMXT2): New define.
(TARGET_REALLY_IWMMXT2): Likewise.
(arm_arch_iwmmxt2): Declare.
* config/arm/mmintrin.h: Use __IWMMXT__ to enable iWMMXt intrinsics.
Use __IWMMXT2__ to enable iWMMXt2 intrinsics.
Use C name-mangling for intrinsics.
(__v8qi): Redefine.
(_mm_cvtsi32_si64, _mm_andnot_si64, _mm_sad_pu8): Revise.
(_mm_sad_pu16, _mm_align_si64, _mm_setwcx, _mm_getwcx): Likewise.
(_m_from_int): Likewise.
(_mm_sada_pu8, _mm_sada_pu16): New intrinsic.
(_mm_alignr0_si64, _mm_alignr1_si64, _mm_alignr2_si64): Likewise.
(_mm_alignr3_si64, _mm_tandcb, _mm_tandch, _mm_tandcw): Likewise.
(_mm_textrcb, _mm_textrch, _mm_textrcw, _mm_torcb): Likewise.
(_mm_torch, _mm_torcw, _mm_tbcst_pi8, _mm_tbcst_pi16): Likewise.
(_mm_tbcst_pi32): Likewise.
(_mm_abs_pi8, _mm_abs_pi16, _mm_abs_pi32): New iWMMXt2 intrinsic.
(_mm_addsubhx_pi16, _mm_absdiff_pu8, _mm_absdiff_pu16): Likewise.
(_mm_absdiff_pu32, _mm_addc_pu16, _mm_addc_pu32): Likewise.
(_mm_avg4_pu8, _mm_avg4r_pu8, _mm_maddx_pi16, _mm_maddx_pu16): Likewise.
(_mm_msub_pi16, _mm_msub_pu16, _mm_mulhi_pi32): Likewise.
(_mm_mulhi_pu32, _mm_mulhir_pi16, _mm_mulhir_pi32): Likewise.
(_mm_mulhir_pu16, _mm_mulhir_pu32, _mm_mullo_pi32): Likewise.
(_mm_qmulm_pi16, _mm_qmulm_pi32, _mm_qmulmr_pi16): Likewise.
(_mm_qmulmr_pi32, _mm_subaddhx_pi16, _mm_addbhusl_pu8): Likewise.
(_mm_addbhusm_pu8, _mm_qmiabb_pi32, _mm_qmiabbn_pi32): Likewise.
(_mm_qmiabt_pi32, _mm_qmiabtn_pi32, _mm_qmiatb_pi32): Likewise.
(_mm_qmiatbn_pi32, _mm_qmiatt_pi32, _mm_qmiattn_pi32): Likewise.
(_mm_wmiabb_si64, _mm_wmiabbn_si64, _mm_wmiabt_si64): Likewise.
(_mm_wmiabtn_si64, _mm_wmiatb_si64, _mm_wmiatbn_si64): Likewise.
(_mm_wmiatt_si64, _mm_wmiattn_si64, _mm_wmiawbb_si64): Likewise.
(_mm_wmiawbbn_si64, _mm_wmiawbt_si64, _mm_wmiawbtn_si64): Likewise.
(_mm_wmiawtb_si64, _mm_wmiawtbn_si64, _mm_wmiawtt_si64): Likewise.
(_mm_wmiawttn_si64, _mm_merge_si64): Likewise.
(_mm_torvscb, _mm_torvsch, _mm_torvscw): Likewise.
(_m_to_int): New define.
* config/arm/arm-cores.def (iwmmxt2): Add FL_IWMMXT2.
* config/arm/arm-arches.def (iwmmxt2): Likewise.
* config/arm/t-arm (MD_INCLUDES): Add marvell-f-iwmmxt.md and
iwmmxt2.md.
* config/arm/arm.md (marvell-f-iwmmxt.md): Include.
(arch): Add "iwmmxt2".
(arch_enabled): Handle "iwmmxt2".
(wtype): New attribute.
(UNSPEC_WMADDS, UNSPEC_WMADDU): Delete.
(UNSPEC_WALIGNI): New unspec.
* config/arm/predicates.md (imm_or_reg_operand): New predicate.
* config/arm/iterators.md (VMMX2): New mode_iterator.
* config/arm/marvell-f-iwmmxt.md: New file.
* config/arm/iwmmxt2.md: New file.
2012-06-12 Jakub Jelinek <jakub@redhat.com>
PR c/53532

View File

@ -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("armv7-m", cortexm3, 7M, FL_CO_PROC | FL_FOR_ARCH7M)
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)

View File

@ -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("arm1020e", arm1020e, 5TE, FL_LDSCHED, fastmul)
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)

View File

@ -159,6 +159,8 @@ extern const char *vfp_output_fstmd (rtx *);
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[]);

View File

@ -684,6 +684,7 @@ static int thumb_call_reg_needed;
#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 \
@ -765,6 +766,9 @@ int arm_arch_cirrus = 0;
/* 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;
@ -1716,6 +1720,7 @@ arm_option_override (void)
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;
@ -1816,14 +1821,17 @@ arm_option_override (void)
}
/* 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");
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 insn patterns need auditing for Thumb-2. */
if (TARGET_THUMB2 && TARGET_IWMMXT)
sorry ("Thumb-2 iWMMXt");
/* 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)
@ -19628,8 +19636,15 @@ static neon_builtin_datum neon_builtin_data[] =
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,
@ -19652,7 +19667,11 @@ enum arm_builtins
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,
@ -19788,6 +19807,81 @@ enum arm_builtins
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,
@ -20320,6 +20414,10 @@ static const struct builtin_description bdesc_2arg[] =
{ 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)
@ -20376,44 +20474,45 @@ static const struct builtin_description bdesc_2arg[] =
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[] =
@ -20436,6 +20535,12 @@ static const struct builtin_description bdesc_1arg[] =
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
@ -20451,9 +20556,6 @@ arm_init_iwmmxt_builtins (void)
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,
@ -20515,6 +20617,9 @@ arm_init_iwmmxt_builtins (void)
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);
@ -20529,12 +20634,10 @@ arm_init_iwmmxt_builtins (void)
= 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);
@ -20550,6 +20653,15 @@ arm_init_iwmmxt_builtins (void)
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,
@ -20562,6 +20674,48 @@ arm_init_iwmmxt_builtins (void)
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,
@ -20619,9 +20773,19 @@ arm_init_iwmmxt_builtins (void)
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);
@ -20653,8 +20817,14 @@ arm_init_iwmmxt_builtins (void)
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);
@ -20676,6 +20846,9 @@ arm_init_iwmmxt_builtins (void)
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);
@ -20701,7 +20874,7 @@ arm_init_iwmmxt_builtins (void)
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);
@ -20709,7 +20882,48 @@ arm_init_iwmmxt_builtins (void)
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
@ -20866,7 +21080,8 @@ arm_expand_binop_builtin (enum insn_code icode,
|| ! (*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);
@ -21365,6 +21580,10 @@ arm_expand_builtin (tree exp,
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);
@ -21399,6 +21618,24 @@ arm_expand_builtin (tree exp,
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))
@ -21409,11 +21646,61 @@ arm_expand_builtin (tree exp,
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);
@ -21432,10 +21719,30 @@ arm_expand_builtin (tree exp,
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))
@ -21446,19 +21753,42 @@ arm_expand_builtin (tree exp,
emit_insn (pat);
return target;
case ARM_BUILTIN_SETWCX:
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));
return 0;
case ARM_BUILTIN_GETWCX:
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);
op0 = expand_normal (arg0);
target = gen_reg_rtx (SImode);
emit_insn (gen_iwmmxt_tmrc (target, op0));
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_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:
@ -21475,10 +21805,12 @@ arm_expand_builtin (tree exp,
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))
@ -21489,10 +21821,18 @@ arm_expand_builtin (tree exp,
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:
@ -21501,13 +21841,38 @@ arm_expand_builtin (tree exp,
/* 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
@ -21516,7 +21881,32 @@ arm_expand_builtin (tree exp,
: 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);
@ -21549,6 +21939,123 @@ arm_expand_builtin (tree exp,
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);
@ -24641,6 +25148,95 @@ arm_output_shift(rtx * operands, int set_flags)
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)

View File

@ -97,6 +97,8 @@ extern char arm_arch_name[];
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 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
#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 @@ extern int arm_arch_cirrus;
/* 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;

View File

@ -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.
@ -197,7 +197,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,neon_onlya8,nota8,neon_nota8"
(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,onlya8,neon_onlya8,nota8,neon_nota8,iwmmxt,iwmmxt2"
(const_string "any"))
(define_attr "arch_enabled" "no,yes"
@ -248,7 +248,12 @@
(and (eq_attr "arch" "neon_nota8")
(not (eq_attr "tune" "cortexa8"))
(match_test "TARGET_NEON"))
(const_string "yes")
(and (eq_attr "arch" "iwmmxt2")
(match_test "TARGET_REALLY_IWMMXT2"))
(const_string "yes")]
(const_string "no")))
; Allows an insn to disable certain alternatives for reasons other than
@ -362,6 +367,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")))
@ -538,6 +547,7 @@
(const_string "yes")
(const_string "no"))))
(include "marvell-f-iwmmxt.md")
(include "arm-generic.md")
(include "arm926ejs.md")
(include "arm1020e.md")

View File

@ -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])

File diff suppressed because it is too large Load Diff

918
gcc/config/arm/iwmmxt2.md Normal file
View File

@ -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
;; <http://www.gnu.org/licenses/>.
(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_wabs<mode>3"
[(set (match_operand:VMMX 0 "register_operand" "=y")
(unspec:VMMX [(match_operand:VMMX 1 "register_operand" "y")] UNSPEC_WABS))]
"TARGET_REALLY_IWMMXT"
"wabs<MMX_char>%?\\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 "addc<mode>3"
[(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"
"wadd<MMX_char>c%?\\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_tandc<mode>3"
[(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<MMX_char>%?\\t r15"
[(set_attr "predicable" "yes")
(set_attr "wtype" "tandc")]
)
(define_insn "iwmmxt_torc<mode>3"
[(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<MMX_char>%?\\t r15"
[(set_attr "predicable" "yes")
(set_attr "wtype" "torc")]
)
(define_insn "iwmmxt_torvsc<mode>3"
[(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<MMX_char>%?\\t r15"
[(set_attr "predicable" "yes")
(set_attr "wtype" "torvsc")]
)
(define_insn "iwmmxt_textrc<mode>3"
[(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<MMX_char>%?\\t r15, %0"
[(set_attr "predicable" "yes")
(set_attr "wtype" "textrc")]
)

View File

@ -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
;; <http://www.gnu.org/licenses/>.
(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")

View File

@ -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,13 +24,23 @@
#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)));
/* Provided for source compatibility with MMX. */
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@ -39,7 +49,7 @@ _mm_empty (void)
}
/* "Convert" __m64 and __int64 into each other. */
static __inline __m64
static __inline __m64
_mm_cvtsi64_m64 (__int64 __i)
{
return __i;
@ -60,7 +70,7 @@ _mm_cvtsi64_si32 (__int64 __i)
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
@ -609,7 +619,7 @@ _mm_and_si64 (__m64 __m1, __m64 __m2)
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. */
@ -941,7 +951,13 @@ _mm_avg2_pu16 (__m64 __A, __m64 __B)
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
@ -950,9 +966,16 @@ _mm_sad_pu8 (__m64 __A, __m64 __B)
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. */
@ -971,11 +994,8 @@ _mm_sadz_pu16 (__m64 __A, __m64 __B)
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
@ -993,42 +1013,76 @@ _mm_setwcx (const int __value, const int __regno)
{
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;
@ -1044,10 +1098,10 @@ _mm_set_pi32 (int __i1, int __i0)
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. */
@ -1114,11 +1168,526 @@ _mm_set1_pi8 (char __b)
return _mm_set1_pi32 (__i);
}
/* Convert an integer to a __m64 object. */
#ifdef __IWMMXT2__
static __inline __m64
_m_from_int (int __a)
_mm_abs_pi8 (__m64 m1)
{
return (__m64)__a;
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
_mm_qmulmr_pi16 (__m64 a, __m64 b)
{
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
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_empty _mm_empty
@ -1257,5 +1826,11 @@ _m_from_int (int __a)
#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 /* __IWMMXT__ */
#endif /* _MMINTRIN_H_INCLUDED */

View File

@ -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.
@ -493,6 +493,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

View File

@ -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 @@ MD_INCLUDES= $(srcdir)/config/arm/arm1020e.md \
$(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 \