Commit eb701deb by Richard Henderson Committed by Richard Henderson

re PR rtl-optimization/13366 (ICE using MMX/SSE builtins with -O)

	PR target/13366
	* config/i386/i386.h (enum ix86_builtins): Move ...
	* config/i386/i386.c: ... here.
	(IX86_BUILTIN_MOVDDUP, IX86_BUILTIN_MMX_ZERO, IX86_BUILTIN_PEXTRW,
	IX86_BUILTIN_PINSRW, IX86_BUILTIN_LOADAPS, IX86_BUILTIN_LOADSS,
	IX86_BUILTIN_STORESS, IX86_BUILTIN_SSE_ZERO, IX86_BUILTIN_PEXTRW128,
	IX86_BUILTIN_PINSRW128, IX86_BUILTIN_LOADAPD, IX86_BUILTIN_LOADSD,
	IX86_BUILTIN_STOREAPD, IX86_BUILTIN_STORESD,  IX86_BUILTIN_STOREHPD,
	IX86_BUILTIN_STORELPD, IX86_BUILTIN_SETPD1, IX86_BUILTIN_SETPD,
	IX86_BUILTIN_CLRPD, IX86_BUILTIN_LOADPD1, IX86_BUILTIN_LOADRPD,
	IX86_BUILTIN_STOREPD1, IX86_BUILTIN_STORERPD, IX86_BUILTIN_LOADDQA,
	IX86_BUILTIN_STOREDQA, IX86_BUILTIN_CLRTI,
	IX86_BUILTIN_LOADDDUP): Remove.
	(IX86_BUILTIN_VEC_INIT_V2SI, IX86_BUILTIN_VEC_INIT_V4HI,
	IX86_BUILTIN_VEC_INIT_V8QI, IX86_BUILTIN_VEC_EXT_V2DF,
	IX86_BUILTIN_VEC_EXT_V2DI, IX86_BUILTIN_VEC_EXT_V4SF,
	IX86_BUILTIN_VEC_EXT_V8HI, IX86_BUILTIN_VEC_EXT_V4HI,
	IX86_BUILTIN_VEC_SET_V8HI, IX86_BUILTIN_VEC_SET_V4HI): New.
	(ix86_init_builtins): Make static.
	(ix86_init_mmx_sse_builtins): Update for changed builtins.
	(ix86_expand_binop_builtin): Only use ix86_fixup_binary_operands
	if all the modes match.  Otherwise, fake it.
	(get_element_number, ix86_expand_vec_init_builtin,
	ix86_expand_vec_ext_builtin, ix86_expand_vec_set_builtin): New.
	(ix86_expand_builtin): Make static.  Update for changed builtins.
	(ix86_expand_vector_move_misalign): Use sse2_loadlpd with zero
	operand instead of sse2_loadsd.  Cast sse1 fallback to V4SFmode.
	(ix86_expand_vector_init_duplicate): New.
	(ix86_expand_vector_init_low_nonzero): New.
	(ix86_expand_vector_init_one_var, ix86_expand_vector_init_general):
	Split out from ix86_expand_vector_init; handle integer modes.
	(ix86_expand_vector_init): Use them.
	(ix86_expand_vector_set, ix86_expand_vector_extract): New.
	* config/i386/i386-protos.h: Update.
	* config/i386/predicates.md (reg_or_0_operand): New.
	* config/i386/mmx.md (mov<MMXMODEI>_internal): Add 'r' variants.
	(movv2sf_internal): Likewise.  And a splitter to match them all.
	(vec_dupv2sf, mmx_concatv2sf, vec_setv2sf, vec_extractv2sf,
	vec_initv2sf, vec_dupv4hi, vec_dupv2si, mmx_concatv2si, vec_setv2si,
	vec_extractv2si, vec_initv2si, vec_setv4hi, vec_extractv4hi,
	vec_initv4hi, vec_setv8qi, vec_extractv8qi, vec_initv8qi): New.
	(mmx_pinsrw): Fix operand ordering.
	* config/i386/sse.md (movv4sf splitter): Use direct pattern,
	rather than sse_loadss expander.
	(movv2df splitter): Similarly.
	(sse_loadss, sse_loadlss): Remove.
	(vec_dupv4sf, sse_concatv2sf, sse_concatv4sf, vec_extractv4sf_0): New.
	(vec_setv4sf, vec_setv2df): Use ix86_expand_vector_set.
	(vec_extractv4sf, vec_extractv2df): Use ix86_expand_vector_extract.
	(sse3_movddup): Rename with '*'.
	(sse3_movddup splitter): Use gen_rtx_REG instead of gen_lowpart.
	(sse2_loadsd): Remove.
	(vec_dupv2df_sse3): Rename from sse3_loadddup.
	(vec_dupv2df, vec_concatv2df_sse3, vec_concatv2df): New.
	(sse2_pinsrw): Fix argument ordering.
	(sse2_loadld, sse2_loadq): Add sse1 alternatives.
	(sse2_stored): Remove 'r' destination.
	(vec_dupv4si, vec_dupv2di, sse2_concatv2si, sse1_concatv2si,
	vec_concatv4si_1, vec_concatv2di, vec_setv2di, vec_extractv2di,
	vec_initv2di, vec_setv4si, vec_extractv4si, vec_initv4si,
	vec_setv8hi, vec_extractv8hi, vec_initv8hi, vec_setv16qi,
	vec_extractv16qi, vec_initv16qi): New.

	* config/i386/emmintrin.h (__m128i, __m128d): Use typedef, not define.
	(_mm_set_sd, _mm_set1_pd, _mm_setzero_pd, _mm_set_epi64x,
	_mm_set_epi32, _mm_set_epi16, _mm_set_epi8, _mm_setzero_si128): Use
	constructor form.
	(_mm_load_pd, _mm_store_pd): Use plain dereference.
	(_mm_load_si128, _mm_store_si128): Likewise.
	(_mm_load1_pd): Use _mm_set1_pd.
	(_mm_load_sd): Use _mm_set_sd.
	(_mm_store_sd, _mm_storeh_pd): Use __builtin_ia32_vec_ext_v2df.
	(_mm_store1_pd, _mm_storer_pd): Use _mm_store_pd.
	(_mm_set_epi64): Use _mm_set_epi64x.
	(_mm_set1_epi64x, _mm_set1_epi64, _mm_set1_epi32, _mm_set_epi16,
	_mm_set1_epi8, _mm_setr_epi64, _mm_setr_epi32, _mm_setr_epi16,
	_mm_setr_epi8): Use _mm_set_foo form.
	(_mm_loadl_epi64, _mm_movpi64_epi64, _mm_move_epi64): Use _mm_set_epi64.
	(_mm_storel_epi64, _mm_movepi64_pi64): Use __builtin_ia32_vec_ext_v2di.
	(_mm_extract_epi16): Use __builtin_ia32_vec_ext_v8hi.
	(_mm_insert_epi16): Use __builtin_ia32_vec_set_v8hi.
	* config/i386/mmintrin.h (_mm_setzero_si64): Use plain cast.
	(_mm_set_pi32): Use __builtin_ia32_vec_init_v2si.
	(_mm_set_pi16): Use __builtin_ia32_vec_init_v4hi.
	(_mm_set_pi8): Use __builtin_ia32_vec_init_v8qi.
	(_mm_set1_pi16, _mm_set1_pi8): Use _mm_set_piN variant.
	* config/i386/pmmintrin.h (_mm_loaddup_pd): Use _mm_load1_pd.
	(_mm_movedup_pd): Use _mm_shuffle_pd.
	* config/i386/xmmintrin.h (_mm_setzero_ps, _mm_set_ss,
	_mm_set1_ps, _mm_set_ps, _mm_setr_ps): Use constructor form.
	(_mm_cvtpi16_ps, _mm_cvtpu16_ps, _mm_cvtpi8_ps, _mm_cvtpu8_ps,
	_mm_cvtps_pi8, _mm_cvtpi32x2_ps): Avoid __builtin_ia32_mmx_zero;
	Use _mm_setzero_ps.
	(_mm_load_ss, _mm_load1_ps): Use _mm_set* form.
	(_mm_load_ps, _mm_loadr_ps): Use raw dereference.
	(_mm_store_ss): Use __builtin_ia32_vec_ext_v4sf.
	(_mm_store_ps): Use raw dereference.
	(_mm_store1_ps): Use _mm_storeu_ps.
	(_mm_storer_ps): Use _mm_store_ps.
	(_mm_extract_pi16): Use __builtin_ia32_vec_ext_v4hi.
	(_mm_insert_pi16): Use __builtin_ia32_vec_set_v4hi.

From-SVN: r93199
parent d9e4e4f5
2005-01-11 Richard Henderson <rth@redhat.com>
PR target/13366
* config/i386/i386.h (enum ix86_builtins): Move ...
* config/i386/i386.c: ... here.
(IX86_BUILTIN_MOVDDUP, IX86_BUILTIN_MMX_ZERO, IX86_BUILTIN_PEXTRW,
IX86_BUILTIN_PINSRW, IX86_BUILTIN_LOADAPS, IX86_BUILTIN_LOADSS,
IX86_BUILTIN_STORESS, IX86_BUILTIN_SSE_ZERO, IX86_BUILTIN_PEXTRW128,
IX86_BUILTIN_PINSRW128, IX86_BUILTIN_LOADAPD, IX86_BUILTIN_LOADSD,
IX86_BUILTIN_STOREAPD, IX86_BUILTIN_STORESD, IX86_BUILTIN_STOREHPD,
IX86_BUILTIN_STORELPD, IX86_BUILTIN_SETPD1, IX86_BUILTIN_SETPD,
IX86_BUILTIN_CLRPD, IX86_BUILTIN_LOADPD1, IX86_BUILTIN_LOADRPD,
IX86_BUILTIN_STOREPD1, IX86_BUILTIN_STORERPD, IX86_BUILTIN_LOADDQA,
IX86_BUILTIN_STOREDQA, IX86_BUILTIN_CLRTI,
IX86_BUILTIN_LOADDDUP): Remove.
(IX86_BUILTIN_VEC_INIT_V2SI, IX86_BUILTIN_VEC_INIT_V4HI,
IX86_BUILTIN_VEC_INIT_V8QI, IX86_BUILTIN_VEC_EXT_V2DF,
IX86_BUILTIN_VEC_EXT_V2DI, IX86_BUILTIN_VEC_EXT_V4SF,
IX86_BUILTIN_VEC_EXT_V8HI, IX86_BUILTIN_VEC_EXT_V4HI,
IX86_BUILTIN_VEC_SET_V8HI, IX86_BUILTIN_VEC_SET_V4HI): New.
(ix86_init_builtins): Make static.
(ix86_init_mmx_sse_builtins): Update for changed builtins.
(ix86_expand_binop_builtin): Only use ix86_fixup_binary_operands
if all the modes match. Otherwise, fake it.
(get_element_number, ix86_expand_vec_init_builtin,
ix86_expand_vec_ext_builtin, ix86_expand_vec_set_builtin): New.
(ix86_expand_builtin): Make static. Update for changed builtins.
(ix86_expand_vector_move_misalign): Use sse2_loadlpd with zero
operand instead of sse2_loadsd. Cast sse1 fallback to V4SFmode.
(ix86_expand_vector_init_duplicate): New.
(ix86_expand_vector_init_low_nonzero): New.
(ix86_expand_vector_init_one_var, ix86_expand_vector_init_general):
Split out from ix86_expand_vector_init; handle integer modes.
(ix86_expand_vector_init): Use them.
(ix86_expand_vector_set, ix86_expand_vector_extract): New.
* config/i386/i386-protos.h: Update.
* config/i386/predicates.md (reg_or_0_operand): New.
* config/i386/mmx.md (mov<MMXMODEI>_internal): Add 'r' variants.
(movv2sf_internal): Likewise. And a splitter to match them all.
(vec_dupv2sf, mmx_concatv2sf, vec_setv2sf, vec_extractv2sf,
vec_initv2sf, vec_dupv4hi, vec_dupv2si, mmx_concatv2si, vec_setv2si,
vec_extractv2si, vec_initv2si, vec_setv4hi, vec_extractv4hi,
vec_initv4hi, vec_setv8qi, vec_extractv8qi, vec_initv8qi): New.
(mmx_pinsrw): Fix operand ordering.
* config/i386/sse.md (movv4sf splitter): Use direct pattern,
rather than sse_loadss expander.
(movv2df splitter): Similarly.
(sse_loadss, sse_loadlss): Remove.
(vec_dupv4sf, sse_concatv2sf, sse_concatv4sf, vec_extractv4sf_0): New.
(vec_setv4sf, vec_setv2df): Use ix86_expand_vector_set.
(vec_extractv4sf, vec_extractv2df): Use ix86_expand_vector_extract.
(sse3_movddup): Rename with '*'.
(sse3_movddup splitter): Use gen_rtx_REG instead of gen_lowpart.
(sse2_loadsd): Remove.
(vec_dupv2df_sse3): Rename from sse3_loadddup.
(vec_dupv2df, vec_concatv2df_sse3, vec_concatv2df): New.
(sse2_pinsrw): Fix argument ordering.
(sse2_loadld, sse2_loadq): Add sse1 alternatives.
(sse2_stored): Remove 'r' destination.
(vec_dupv4si, vec_dupv2di, sse2_concatv2si, sse1_concatv2si,
vec_concatv4si_1, vec_concatv2di, vec_setv2di, vec_extractv2di,
vec_initv2di, vec_setv4si, vec_extractv4si, vec_initv4si,
vec_setv8hi, vec_extractv8hi, vec_initv8hi, vec_setv16qi,
vec_extractv16qi, vec_initv16qi): New.
* config/i386/emmintrin.h (__m128i, __m128d): Use typedef, not define.
(_mm_set_sd, _mm_set1_pd, _mm_setzero_pd, _mm_set_epi64x,
_mm_set_epi32, _mm_set_epi16, _mm_set_epi8, _mm_setzero_si128): Use
constructor form.
(_mm_load_pd, _mm_store_pd): Use plain dereference.
(_mm_load_si128, _mm_store_si128): Likewise.
(_mm_load1_pd): Use _mm_set1_pd.
(_mm_load_sd): Use _mm_set_sd.
(_mm_store_sd, _mm_storeh_pd): Use __builtin_ia32_vec_ext_v2df.
(_mm_store1_pd, _mm_storer_pd): Use _mm_store_pd.
(_mm_set_epi64): Use _mm_set_epi64x.
(_mm_set1_epi64x, _mm_set1_epi64, _mm_set1_epi32, _mm_set_epi16,
_mm_set1_epi8, _mm_setr_epi64, _mm_setr_epi32, _mm_setr_epi16,
_mm_setr_epi8): Use _mm_set_foo form.
(_mm_loadl_epi64, _mm_movpi64_epi64, _mm_move_epi64): Use _mm_set_epi64.
(_mm_storel_epi64, _mm_movepi64_pi64): Use __builtin_ia32_vec_ext_v2di.
(_mm_extract_epi16): Use __builtin_ia32_vec_ext_v8hi.
(_mm_insert_epi16): Use __builtin_ia32_vec_set_v8hi.
* config/i386/mmintrin.h (_mm_setzero_si64): Use plain cast.
(_mm_set_pi32): Use __builtin_ia32_vec_init_v2si.
(_mm_set_pi16): Use __builtin_ia32_vec_init_v4hi.
(_mm_set_pi8): Use __builtin_ia32_vec_init_v8qi.
(_mm_set1_pi16, _mm_set1_pi8): Use _mm_set_piN variant.
* config/i386/pmmintrin.h (_mm_loaddup_pd): Use _mm_load1_pd.
(_mm_movedup_pd): Use _mm_shuffle_pd.
* config/i386/xmmintrin.h (_mm_setzero_ps, _mm_set_ss,
_mm_set1_ps, _mm_set_ps, _mm_setr_ps): Use constructor form.
(_mm_cvtpi16_ps, _mm_cvtpu16_ps, _mm_cvtpi8_ps, _mm_cvtpu8_ps,
_mm_cvtps_pi8, _mm_cvtpi32x2_ps): Avoid __builtin_ia32_mmx_zero;
Use _mm_setzero_ps.
(_mm_load_ss, _mm_load1_ps): Use _mm_set* form.
(_mm_load_ps, _mm_loadr_ps): Use raw dereference.
(_mm_store_ss): Use __builtin_ia32_vec_ext_v4sf.
(_mm_store_ps): Use raw dereference.
(_mm_store1_ps): Use _mm_storeu_ps.
(_mm_storer_ps): Use _mm_store_ps.
(_mm_extract_pi16): Use __builtin_ia32_vec_ext_v4hi.
(_mm_insert_pi16): Use __builtin_ia32_vec_set_v4hi.
2005-01-11 Stan Shebs <shebs@apple.com>
* config/rs6000/rs6000.c (machopic_output_stub): Issue
......
......@@ -198,8 +198,6 @@ extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
tree, int);
extern rtx ix86_function_value (tree);
extern void ix86_init_builtins (void);
extern rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
#endif
#endif
......@@ -219,7 +217,10 @@ extern int x86_field_alignment (tree, int);
extern rtx ix86_tls_get_addr (void);
extern void ix86_expand_vector_init (rtx, rtx);
extern void ix86_expand_vector_init (bool, rtx, rtx);
extern void ix86_expand_vector_set (bool, rtx, rtx, int);
extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
/* In winnt.c */
extern int i386_pe_dllexport_name_p (const char *);
extern int i386_pe_dllimport_name_p (const char *);
......
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -818,35 +818,21 @@ _m_pcmpgtd (__m64 __m1, __m64 __m2)
static __inline __m64
_mm_setzero_si64 (void)
{
return (__m64)__builtin_ia32_mmx_zero ();
return (__m64)0LL;
}
/* Creates a vector of two 32-bit values; I0 is least significant. */
static __inline __m64
_mm_set_pi32 (int __i1, int __i0)
{
union {
__m64 __q;
struct {
unsigned int __i0;
unsigned int __i1;
} __s;
} __u;
__u.__s.__i0 = __i0;
__u.__s.__i1 = __i1;
return __u.__q;
return (__m64) __builtin_ia32_vec_init_v2si (__i0, __i1);
}
/* Creates a vector of four 16-bit values; W0 is least significant. */
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;
return _mm_set_pi32 (__i1, __i0);
return (__m64) __builtin_ia32_vec_init_v4hi (__w0, __w1, __w2, __w3);
}
/* Creates a vector of eight 8-bit values; B0 is least significant. */
......@@ -854,19 +840,8 @@ static __inline __m64
_mm_set_pi8 (char __b7, char __b6, char __b5, char __b4,
char __b3, char __b2, char __b1, char __b0)
{
unsigned int __i1, __i0;
__i1 = (unsigned char)__b7;
__i1 = __i1 << 8 | (unsigned char)__b6;
__i1 = __i1 << 8 | (unsigned char)__b5;
__i1 = __i1 << 8 | (unsigned char)__b4;
__i0 = (unsigned char)__b3;
__i0 = __i0 << 8 | (unsigned char)__b2;
__i0 = __i0 << 8 | (unsigned char)__b1;
__i0 = __i0 << 8 | (unsigned char)__b0;
return _mm_set_pi32 (__i1, __i0);
return (__m64) __builtin_ia32_vec_init_v8qi (__b0, __b1, __b2, __b3,
__b4, __b5, __b6, __b7);
}
/* Similar, but with the arguments in reverse order. */
......@@ -900,17 +875,14 @@ _mm_set1_pi32 (int __i)
static __inline __m64
_mm_set1_pi16 (short __w)
{
unsigned int __i = (unsigned short)__w << 16 | (unsigned short)__w;
return _mm_set1_pi32 (__i);
return _mm_set_pi16 (__w, __w, __w, __w);
}
/* Creates a vector of eight 8-bit values, all elements containing B. */
static __inline __m64
_mm_set1_pi8 (char __b)
{
unsigned int __w = (unsigned char)__b << 8 | (unsigned char)__b;
unsigned int __i = __w << 16 | __w;
return _mm_set1_pi32 (__i);
return _mm_set_pi8 (__b, __b, __b, __b, __b, __b, __b, __b);
}
#endif /* __MMX__ */
......
......@@ -87,9 +87,9 @@
(define_insn "*mov<mode>_internal"
[(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
"=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m")
"=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m ,?r ,?m")
(match_operand:MMXMODEI 1 "vector_move_operand"
"C ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x"))]
"C ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x,irm,r"))]
"TARGET_MMX
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
......@@ -104,9 +104,11 @@
xorps\t%0, %0
movaps\t{%1, %0|%0, %1}
movlps\t{%1, %0|%0, %1}
movlps\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov")
(set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF")])
movlps\t{%1, %0|%0, %1}
#
#"
[(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,ssemov,*,*")
(set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
(define_expand "movv2sf"
[(set (match_operand:V2SF 0 "nonimmediate_operand" "")
......@@ -142,9 +144,9 @@
(define_insn "*movv2sf_internal"
[(set (match_operand:V2SF 0 "nonimmediate_operand"
"=*y,*y ,m,*y,*Y,*x,*x ,m")
"=*y,*y ,m,*y,*Y,*x,*x ,m ,?r ,?m")
(match_operand:V2SF 1 "vector_move_operand"
"C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
"C ,*ym,*y,*Y,*y,C ,*xm,*x,irm,r"))]
"TARGET_MMX
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
......@@ -155,9 +157,21 @@
movq2dq\t{%1, %0|%0, %1}
xorps\t%0, %0
movlps\t{%1, %0|%0, %1}
movlps\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
(set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF")])
movlps\t{%1, %0|%0, %1}
#
#"
[(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,*,*")
(set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
;; %%% This multiword shite has got to go.
(define_split
[(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
(match_operand:MMXMODE 1 "general_operand" ""))]
"!TARGET_64BIT && reload_completed
&& (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
&& (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
(define_expand "movmisalign<mode>"
[(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
......@@ -426,6 +440,58 @@
[(set_attr "type" "mmxcvt")
(set_attr "mode" "V2SF")])
(define_insn "*vec_dupv2sf"
[(set (match_operand:V2SF 0 "register_operand" "=y")
(vec_duplicate:V2SF
(match_operand:SF 1 "register_operand" "0")))]
"TARGET_MMX"
"punpckldq\t%0, %0"
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
(define_insn "*mmx_concatv2sf"
[(set (match_operand:V2SF 0 "register_operand" "=y,y")
(vec_concat:V2SF
(match_operand:SF 1 "nonimmediate_operand" " 0,rm")
(match_operand:SF 2 "vector_move_operand" "ym,C")))]
"TARGET_MMX && !TARGET_SSE"
"@
punpckldq\t{%2, %0|%0, %2}
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt,mmxmov")
(set_attr "mode" "DI")])
(define_expand "vec_setv2sf"
[(match_operand:V2SF 0 "register_operand" "")
(match_operand:SF 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_set (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv2sf"
[(match_operand:SF 0 "register_operand" "")
(match_operand:V2SF 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_extract (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_initv2sf"
[(match_operand:V2SF 0 "register_operand" "")
(match_operand 1 "" "")]
"TARGET_SSE"
{
ix86_expand_vector_init (false, operands[0], operands[1]);
DONE;
})
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Parallel integral arithmetic
......@@ -902,9 +968,9 @@
(define_expand "mmx_pinsrw"
[(set (match_operand:V4HI 0 "register_operand" "")
(vec_merge:V4HI
(match_operand:V4HI 1 "register_operand" "")
(vec_duplicate:V4HI
(match_operand:SI 2 "nonimmediate_operand" ""))
(match_operand:V4HI 1 "register_operand" "")
(match_operand:SI 3 "const_0_to_3_operand" "")))]
"TARGET_SSE || TARGET_3DNOW_A"
{
......@@ -915,9 +981,9 @@
(define_insn "*mmx_pinsrw"
[(set (match_operand:V4HI 0 "register_operand" "=y")
(vec_merge:V4HI
(match_operand:V4HI 1 "register_operand" "0")
(vec_duplicate:V4HI
(match_operand:HI 2 "nonimmediate_operand" "rm"))
(match_operand:V4HI 1 "register_operand" "0")
(match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))]
"TARGET_SSE || TARGET_3DNOW_A"
{
......@@ -938,7 +1004,6 @@
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
(define_expand "mmx_pshufw"
[(match_operand:V4HI 0 "register_operand" "")
(match_operand:V4HI 1 "nonimmediate_operand" "")
......@@ -986,6 +1051,130 @@
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
(define_insn "*vec_dupv4hi"
[(set (match_operand:V4HI 0 "register_operand" "=y")
(vec_duplicate:V4HI
(truncate:HI
(match_operand:SI 1 "register_operand" "0"))))]
"TARGET_MMX"
"pshufw\t{$0, %0, %0|%0, %0, 0}"
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
(define_insn "*vec_dupv2si"
[(set (match_operand:V2SI 0 "register_operand" "=y")
(vec_duplicate:V2SI
(match_operand:SI 1 "register_operand" "0")))]
"TARGET_MMX"
"punpckldq\t%0, %0"
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
(define_insn "*mmx_concatv2si"
[(set (match_operand:V2SI 0 "register_operand" "=y,y")
(vec_concat:V2SI
(match_operand:SI 1 "nonimmediate_operand" " 0,rm")
(match_operand:SI 2 "vector_move_operand" "ym,C")))]
"TARGET_MMX && !TARGET_SSE"
"@
punpckldq\t{%2, %0|%0, %2}
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt,mmxmov")
(set_attr "mode" "DI")])
(define_expand "vec_setv2si"
[(match_operand:V2SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_set (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv2si"
[(match_operand:SI 0 "register_operand" "")
(match_operand:V2SI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_extract (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_initv2si"
[(match_operand:V2SI 0 "register_operand" "")
(match_operand 1 "" "")]
"TARGET_SSE"
{
ix86_expand_vector_init (false, operands[0], operands[1]);
DONE;
})
(define_expand "vec_setv4hi"
[(match_operand:V4HI 0 "register_operand" "")
(match_operand:HI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_set (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv4hi"
[(match_operand:HI 0 "register_operand" "")
(match_operand:V4HI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_extract (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_initv4hi"
[(match_operand:V4HI 0 "register_operand" "")
(match_operand 1 "" "")]
"TARGET_SSE"
{
ix86_expand_vector_init (false, operands[0], operands[1]);
DONE;
})
(define_expand "vec_setv8qi"
[(match_operand:V8QI 0 "register_operand" "")
(match_operand:QI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_set (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_extractv8qi"
[(match_operand:QI 0 "register_operand" "")
(match_operand:V8QI 1 "register_operand" "")
(match_operand 2 "const_int_operand" "")]
"TARGET_MMX"
{
ix86_expand_vector_extract (false, operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_expand "vec_initv8qi"
[(match_operand:V8QI 0 "register_operand" "")
(match_operand 1 "" "")]
"TARGET_SSE"
{
ix86_expand_vector_init (false, operands[0], operands[1]);
DONE;
})
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Miscellaneous
......
......@@ -95,13 +95,13 @@ _mm_hsub_pd (__m128d __X, __m128d __Y)
static __inline __m128d
_mm_loaddup_pd (double const *__P)
{
return (__m128d) __builtin_ia32_loadddup (__P);
return _mm_load1_pd (__P);
}
static __inline __m128d
_mm_movedup_pd (__m128d __X)
{
return (__m128d) __builtin_ia32_movddup ((__v2df)__X);
return _mm_shuffle_pd (__X, __X, _MM_SHUFFLE2 (0,0));
}
static __inline __m128i
......
......@@ -641,6 +641,11 @@
(ior (match_operand 0 "nonimmediate_operand")
(match_operand 0 "const0_operand")))
;; Return true if OP is a register or a zero.
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const0_operand")))
;; Return true if op if a valid address, and does not contain
;; a segment override.
(define_special_predicate "no_seg_address_operand"
......
/* { dg-do compile } */
/* { dg-options "-O -msse" } */
#include <xmmintrin.h>
typedef unsigned short v4hi __attribute__ ((vector_size (8)));
int f(unsigned short n)
{
__m64 vec = (__m64)(v4hi){ 0, 0, 1, n };
__m64 hw = _mm_mulhi_pi16 (vec, vec);
return _mm_extract_pi16 (hw, 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment