aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2009-11-25 20:32:37 +0100
committerUros Bizjak <uros@gcc.gnu.org>2009-11-25 20:32:37 +0100
commit85b1d1bd1aeba0edb8625894287dba91350fb929 (patch)
treede5cb0022bf5f27ba2fbef2e3ef42138e51f0084
parent5115f061bf337a8e3474b95615c716b7bb4a9df6 (diff)
downloadgcc-85b1d1bd1aeba0edb8625894287dba91350fb929.zip
gcc-85b1d1bd1aeba0edb8625894287dba91350fb929.tar.gz
gcc-85b1d1bd1aeba0edb8625894287dba91350fb929.tar.bz2
predicates.md (emms_operation): New predicate.
* config/i386/predicates.md (emms_operation): New predicate. (vzeroupper_operation): Ditto. (vzeroall_operation): Improve pattern recognition. * config/i386/sse.md (avx_vzeroupper_rex64): Remove insn pattern. (avx_vzeroupper): Change insn pattern to expander. (*avx_vzeroupper): New insn pattern. Use vzeroupper_operation predicate. (*avx_vzeroall): Remove operands 1 and 2. * config/i386/mmx.md (mmx_emms): Change insn pattern to expander. (mmx_femms): Ditto. (*mmx_emms): New insn pattern. Use emms_operation predicate. (*mmx_femms): Ditto. * config/i386/i386.c (enum ix86_builtins) <IX86_BUILTIN_VZEROUPPER_REX64>: Remove. (struct builtin_description) <CODE_FOR_avx_vzeroupper_rex64>: Remove initailization. <CODE_FOR_avx_vzeroupper>: Unconditionally initialize here. From-SVN: r154649
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/i386/i386.c10
-rw-r--r--gcc/config/i386/mmx.md94
-rw-r--r--gcc/config/i386/predicates.md67
-rw-r--r--gcc/config/i386/sse.md62
5 files changed, 165 insertions, 88 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff72fed..5579460 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+2009-11-25 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/predicates.md (emms_operation): New predicate.
+ (vzeroupper_operation): Ditto.
+ (vzeroall_operation): Improve pattern recognition.
+ * config/i386/sse.md (avx_vzeroupper_rex64): Remove insn pattern.
+ (avx_vzeroupper): Change insn pattern to expander.
+ (*avx_vzeroupper): New insn pattern. Use vzeroupper_operation
+ predicate.
+ (*avx_vzeroall): Remove operands 1 and 2.
+ * config/i386/mmx.md (mmx_emms): Change insn pattern to expander.
+ (mmx_femms): Ditto.
+ (*mmx_emms): New insn pattern. Use emms_operation predicate.
+ (*mmx_femms): Ditto.
+ * config/i386/i386.c (enum ix86_builtins)
+ <IX86_BUILTIN_VZEROUPPER_REX64>: Remove.
+ (struct builtin_description) <CODE_FOR_avx_vzeroupper_rex64>:
+ Remove initailization.
+ <CODE_FOR_avx_vzeroupper>: Unconditionally initialize here.
+
2009-11-25 Paul Brook <paul@codesourcery.com>
* config/arm/arm.md (consttable_4): Handle (high ...).
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4310e49..5bce7a4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -20941,7 +20941,6 @@ enum ix86_builtins
IX86_BUILTIN_EXTRACTF128SI256,
IX86_BUILTIN_VZEROALL,
IX86_BUILTIN_VZEROUPPER,
- IX86_BUILTIN_VZEROUPPER_REX64,
IX86_BUILTIN_VPERMILVARPD,
IX86_BUILTIN_VPERMILVARPS,
IX86_BUILTIN_VPERMILVARPD256,
@@ -21465,8 +21464,7 @@ static const struct builtin_description bdesc_special_args[] =
/* AVX */
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroall, "__builtin_ia32_vzeroall", IX86_BUILTIN_VZEROALL, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroupper, 0, IX86_BUILTIN_VZEROUPPER, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_64BIT, CODE_FOR_avx_vzeroupper_rex64, 0, IX86_BUILTIN_VZEROUPPER_REX64, UNKNOWN, (int) VOID_FTYPE_VOID },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroupper, "__builtin_ia32_vzeroupper", IX86_BUILTIN_VZEROUPPER, UNKNOWN, (int) VOID_FTYPE_VOID },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastss, "__builtin_ia32_vbroadcastss", IX86_BUILTIN_VBROADCASTSS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastsd256, "__builtin_ia32_vbroadcastsd256", IX86_BUILTIN_VBROADCASTSD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
@@ -22481,12 +22479,6 @@ ix86_init_mmx_sse_builtins (void)
def_builtin_const (OPTION_MASK_ISA_PCLMUL, "__builtin_ia32_pclmulqdq128",
V2DI_FTYPE_V2DI_V2DI_INT, IX86_BUILTIN_PCLMULQDQ128);
- /* AVX */
- def_builtin (OPTION_MASK_ISA_AVX, "__builtin_ia32_vzeroupper",
- VOID_FTYPE_VOID,
- (TARGET_64BIT ? IX86_BUILTIN_VZEROUPPER_REX64
- : IX86_BUILTIN_VZEROUPPER));
-
/* MMX access to the vec_init patterns. */
def_builtin_const (OPTION_MASK_ISA_MMX, "__builtin_ia32_vec_init_v2si",
V2SI_FTYPE_INT_INT, IX86_BUILTIN_VEC_INIT_V2SI);
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index dea9322..83c54b2 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1640,48 +1640,66 @@
[(set_attr "type" "mmxcvt")
(set_attr "mode" "DI")])
-(define_insn "mmx_emms"
- [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
- (clobber (reg:XF ST0_REG))
- (clobber (reg:XF ST1_REG))
- (clobber (reg:XF ST2_REG))
- (clobber (reg:XF ST3_REG))
- (clobber (reg:XF ST4_REG))
- (clobber (reg:XF ST5_REG))
- (clobber (reg:XF ST6_REG))
- (clobber (reg:XF ST7_REG))
- (clobber (reg:DI MM0_REG))
- (clobber (reg:DI MM1_REG))
- (clobber (reg:DI MM2_REG))
- (clobber (reg:DI MM3_REG))
- (clobber (reg:DI MM4_REG))
- (clobber (reg:DI MM5_REG))
- (clobber (reg:DI MM6_REG))
- (clobber (reg:DI MM7_REG))]
+(define_expand "mmx_emms"
+ [(match_par_dup 0 [(const_int 0)])]
+ "TARGET_MMX"
+{
+ int regno;
+
+ operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
+
+ XVECEXP (operands[0], 0, 0)
+ = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
+ UNSPECV_EMMS);
+
+ for (regno = 0; regno < 8; regno++)
+ {
+ XVECEXP (operands[0], 0, regno + 1)
+ = gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
+
+ XVECEXP (operands[0], 0, regno + 9)
+ = gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
+ }
+})
+
+(define_insn "*mmx_emms"
+ [(match_parallel 0 "emms_operation"
+ [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
"TARGET_MMX"
"emms"
[(set_attr "type" "mmx")
(set_attr "modrm" "0")
- (set_attr "memory" "unknown")])
-
-(define_insn "mmx_femms"
- [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
- (clobber (reg:XF ST0_REG))
- (clobber (reg:XF ST1_REG))
- (clobber (reg:XF ST2_REG))
- (clobber (reg:XF ST3_REG))
- (clobber (reg:XF ST4_REG))
- (clobber (reg:XF ST5_REG))
- (clobber (reg:XF ST6_REG))
- (clobber (reg:XF ST7_REG))
- (clobber (reg:DI MM0_REG))
- (clobber (reg:DI MM1_REG))
- (clobber (reg:DI MM2_REG))
- (clobber (reg:DI MM3_REG))
- (clobber (reg:DI MM4_REG))
- (clobber (reg:DI MM5_REG))
- (clobber (reg:DI MM6_REG))
- (clobber (reg:DI MM7_REG))]
+ (set_attr "memory" "none")])
+
+(define_expand "mmx_femms"
+ [(match_par_dup 0 [(const_int 0)])]
+ "TARGET_3DNOW"
+{
+ int regno;
+
+ operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
+
+ XVECEXP (operands[0], 0, 0)
+ = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
+ UNSPECV_FEMMS);
+
+ for (regno = 0; regno < 8; regno++)
+ {
+ XVECEXP (operands[0], 0, regno + 1)
+ = gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
+
+ XVECEXP (operands[0], 0, regno + 9)
+ = gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
+ }
+})
+
+(define_insn "*mmx_femms"
+ [(match_parallel 0 "emms_operation"
+ [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
"TARGET_3DNOW"
"femms"
[(set_attr "type" "mmx")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 74d2f96..7200a6a 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1132,15 +1132,78 @@
(and (match_code "mem")
(match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)")))
+;; Return 1 if OP is a emms operation, known to be a PARALLEL.
+(define_predicate "emms_operation"
+ (match_code "parallel")
+{
+ unsigned i;
+
+ if (XVECLEN (op, 0) != 17)
+ return 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+1);
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != XFmode
+ || REGNO (SET_DEST (elt)) != FIRST_STACK_REG + i)
+ return 0;
+
+ elt = XVECEXP (op, 0, i+9);
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != DImode
+ || REGNO (SET_DEST (elt)) != FIRST_MMX_REG + i)
+ return 0;
+ }
+ return 1;
+})
+
;; Return 1 if OP is a vzeroall operation, known to be a PARALLEL.
(define_predicate "vzeroall_operation"
(match_code "parallel")
{
- int nregs = TARGET_64BIT ? 16 : 8;
+ unsigned i, nregs = TARGET_64BIT ? 16 : 8;
- if (XVECLEN (op, 0) != nregs + 1)
+ if ((unsigned) XVECLEN (op, 0) != 1 + nregs)
return 0;
+ for (i = 0; i < nregs; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+1);
+
+ if (GET_CODE (elt) != SET
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != V8SImode
+ || REGNO (SET_DEST (elt)) != SSE_REGNO (i)
+ || SET_SRC (elt) != CONST0_RTX (V8SImode))
+ return 0;
+ }
+ return 1;
+})
+
+;; Return 1 if OP is a vzeroupper operation, known to be a PARALLEL.
+(define_predicate "vzeroupper_operation"
+ (match_code "parallel")
+{
+ unsigned i, nregs = TARGET_64BIT ? 16 : 8;
+
+ if ((unsigned) XVECLEN (op, 0) != 1 + nregs)
+ return 0;
+
+ for (i = 0; i < nregs; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+1);
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != V8SImode
+ || REGNO (SET_DEST (elt)) != SSE_REGNO (i))
+ return 0;
+ }
return 1;
})
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 79adc77..4944fac 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -12033,9 +12033,7 @@
(define_insn "*avx_vzeroall"
[(match_parallel 0 "vzeroall_operation"
- [(unspec_volatile [(const_int 0)] UNSPECV_VZEROALL)
- (set (match_operand 1 "register_operand" "=x")
- (match_operand 2 "const0_operand" "X"))])]
+ [(unspec_volatile [(const_int 0)] UNSPECV_VZEROALL)])]
"TARGET_AVX"
"vzeroall"
[(set_attr "type" "sse")
@@ -12045,43 +12043,29 @@
(set_attr "mode" "OI")])
;; vzeroupper clobbers the upper 128bits of AVX registers.
-(define_insn "avx_vzeroupper"
- [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER)
- (clobber (reg:V8SI XMM0_REG))
- (clobber (reg:V8SI XMM1_REG))
- (clobber (reg:V8SI XMM2_REG))
- (clobber (reg:V8SI XMM3_REG))
- (clobber (reg:V8SI XMM4_REG))
- (clobber (reg:V8SI XMM5_REG))
- (clobber (reg:V8SI XMM6_REG))
- (clobber (reg:V8SI XMM7_REG))]
- "TARGET_AVX && !TARGET_64BIT"
- "vzeroupper"
- [(set_attr "type" "sse")
- (set_attr "modrm" "0")
- (set_attr "memory" "none")
- (set_attr "prefix" "vex")
- (set_attr "mode" "OI")])
+(define_expand "avx_vzeroupper"
+ [(match_par_dup 0 [(const_int 0)])]
+ "TARGET_AVX"
+{
+ int nregs = TARGET_64BIT ? 16 : 8;
+ int regno;
-(define_insn "avx_vzeroupper_rex64"
- [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER)
- (clobber (reg:V8SI XMM0_REG))
- (clobber (reg:V8SI XMM1_REG))
- (clobber (reg:V8SI XMM2_REG))
- (clobber (reg:V8SI XMM3_REG))
- (clobber (reg:V8SI XMM4_REG))
- (clobber (reg:V8SI XMM5_REG))
- (clobber (reg:V8SI XMM6_REG))
- (clobber (reg:V8SI XMM7_REG))
- (clobber (reg:V8SI XMM8_REG))
- (clobber (reg:V8SI XMM9_REG))
- (clobber (reg:V8SI XMM10_REG))
- (clobber (reg:V8SI XMM11_REG))
- (clobber (reg:V8SI XMM12_REG))
- (clobber (reg:V8SI XMM13_REG))
- (clobber (reg:V8SI XMM14_REG))
- (clobber (reg:V8SI XMM15_REG))]
- "TARGET_AVX && TARGET_64BIT"
+ operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
+
+ XVECEXP (operands[0], 0, 0)
+ = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
+ UNSPECV_VZEROUPPER);
+
+ for (regno = 0; regno < nregs; regno++)
+ XVECEXP (operands[0], 0, regno + 1)
+ = gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_REG (V8SImode, SSE_REGNO (regno)));
+})
+
+(define_insn "*avx_vzeroupper"
+ [(match_parallel 0 "vzeroupper_operation"
+ [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER)])]
+ "TARGET_AVX"
"vzeroupper"
[(set_attr "type" "sse")
(set_attr "modrm" "0")