diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff72fed0628..55794601125 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2009-11-25 Uros Bizjak + + * 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) + : Remove. + (struct builtin_description) : + Remove initailization. + : Unconditionally initialize here. + 2009-11-25 Paul Brook * config/arm/arm.md (consttable_4): Handle (high ...). diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 4310e49cfbc..5bce7a4d0db 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 dea9322f9a8..83c54b28f3a 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")]) + (set_attr "memory" "none")]) -(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))] +(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 74d2f9633d3..7200a6a2167 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 79adc77a628..4944facc63d 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")