There is no need to dynamically construct clobbers of (f)emms insn. Also, use faster detection of vzeroall pattern.
2018-09-30 Uros Bizjak <ubiz...@gmail.com> * config/i386/mmx.md (EMMS): New int iterator. (emms): New int attribute. (mmx_<emms>): Macroize insn from *mmx_emms and *mmx_femms using EMMS int iterator. Explicitly declare clobbers. (mmx_emms): Remove expander. (mmx_femms): Ditto. * config/i386/predicates.md (emms_operation): Remove predicate. (vzeroall_pattern): New predicate. (vzeroupper_pattern): Rename from vzeroupper_operation. * config/i386/i386.c (ix86_avx_u128_mode_after): Use vzeroupper_pattern and vzeroall_pattern predicates. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 264695) +++ config/i386/i386.c (working copy) @@ -18944,8 +18944,8 @@ ix86_avx_u128_mode_after (int mode, rtx_insn *insn { rtx pat = PATTERN (insn); - if (vzeroupper_operation (pat, VOIDmode) - || vzeroall_operation (pat, VOIDmode)) + if (vzeroupper_pattern (pat, VOIDmode) + || vzeroall_pattern (pat, VOIDmode)) return AVX_U128_CLEAN; /* We know that state is clean after CALL insn if there are no Index: config/i386/mmx.md =================================================================== --- config/i386/mmx.md (revision 264693) +++ config/i386/mmx.md (working copy) @@ -1570,68 +1570,34 @@ (set_attr "znver1_decode" "vector") (set_attr "mode" "DI")]) -(define_expand "mmx_emms" - [(match_par_dup 0 [(const_int 0)])] - "TARGET_MMX" -{ - int regno; +(define_int_iterator EMMS + [(UNSPECV_EMMS "TARGET_MMX") + (UNSPECV_FEMMS "TARGET_3DNOW")]) - operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17)); +(define_int_attr emms + [(UNSPECV_EMMS "emms") + (UNSPECV_FEMMS "femms")]) - 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" +(define_insn "mmx_<emms>" + [(unspec_volatile [(const_int 0)] 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))] + "" + "<emms>" [(set_attr "type" "mmx") (set_attr "modrm" "0") (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") - (set_attr "modrm" "0") - (set_attr "memory" "none")]) Index: config/i386/predicates.md =================================================================== --- config/i386/predicates.md (revision 264695) +++ config/i386/predicates.md (working copy) @@ -1406,36 +1406,6 @@ (and (match_code "mem") (match_test "MEM_ALIGN (op) < GET_MODE_BITSIZE (mode)"))) -;; Return true 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 false; - - 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 false; - - 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 false; - } - return true; -}) - ;; Return true if OP is a vzeroall operation, known to be a PARALLEL. (define_predicate "vzeroall_operation" (match_code "parallel") @@ -1459,8 +1429,14 @@ return true; }) -;; return true if OP is a vzeroupper operation. -(define_predicate "vzeroupper_operation" +;; return true if OP is a vzeroall pattern. +(define_predicate "vzeroall_pattern" + (and (match_code "parallel") + (match_code "unspec_volatile" "a") + (match_test "XINT (XVECEXP (op, 0, 0), 1) == UNSPECV_VZEROALL"))) + +;; return true if OP is a vzeroupper pattern. +(define_predicate "vzeroupper_pattern" (and (match_code "unspec_volatile") (match_test "XINT (op, 1) == UNSPECV_VZEROUPPER")))