Commit c5b1ea25 by Uros Bizjak

i386.md (*tzcnt<mode>_1): Merge *tzcnt<mode>_1_falsedep_1 and *tzcnt<mode>_1 to…

i386.md (*tzcnt<mode>_1): Merge *tzcnt<mode>_1_falsedep_1 and *tzcnt<mode>_1 to define_insn_and_split pattern.

	* config/i386/i386.md (*tzcnt<mode>_1): Merge *tzcnt<mode>_1_falsedep_1
	and *tzcnt<mode>_1 to define_insn_and_split pattern.  Adjust split
	condition to split after epilogue_completed.
	(ctz<mode>2): Remove expander.
	(ctz<mode>2): Merge *ctz<mode>2_falsedep_1 and *ctz<mode>2 to
	define_insn_and_split pattern.  Adjust split condition to split
	after epilogue_completed.
	(clz<mode>2_lznct): Remove expander.
	(clz<mode>2_lzcnt): Merge *clz<mode>2_lzcnt_falsedep_1 and
	*clz<mode>2 to define_insn_and_split pattern.  Adjust split
	condition to split after epilogue_completed.
	(<lt_zcnt>_<mode>): Remove expander.
	(<lt_zcnt>_<mode>): Merge *<lt_zcnt>_<mode>_falsedep_1 and
	*<lt_zcnt>_<mode> to define_insn_and_split pattern.  Adjust split
	condition to split after epilogue_completed.
	(<lt_zcnt>_hi): New insn pattern.
	(popcount<mode>2): Remove expander.
	(popcount<mode>2): Merge *popcount<mode>2_falsedep_1 and
	*popcount<mode>2 to define_insn_and_split pattern.  Adjust split
	condition to split after epilogue_completed.
	(popcounthi2): New insn pattern.

From-SVN: r243772
parent 6040f6d4
2016-12-17 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*tzcnt<mode>_1): Merge *tzcnt<mode>_1_falsedep_1
and *tzcnt<mode>_1 to define_insn_and_split pattern. Adjust split
condition to split after epilogue_completed.
(ctz<mode>2): Remove expander.
(ctz<mode>2): Merge *ctz<mode>2_falsedep_1 and *ctz<mode>2 to
define_insn_and_split pattern. Adjust split condition to split
after epilogue_completed.
(clz<mode>2_lznct): Remove expander.
(clz<mode>2_lzcnt): Merge *clz<mode>2_lzcnt_falsedep_1 and
*clz<mode>2 to define_insn_and_split pattern. Adjust split
condition to split after epilogue_completed.
(<lt_zcnt>_<mode>): Remove expander.
(<lt_zcnt>_<mode>): Merge *<lt_zcnt>_<mode>_falsedep_1 and
*<lt_zcnt>_<mode> to define_insn_and_split pattern. Adjust split
condition to split after epilogue_completed.
(<lt_zcnt>_hi): New insn pattern.
(popcount<mode>2): Remove expander.
(popcount<mode>2): Merge *popcount<mode>2_falsedep_1 and
*popcount<mode>2 to define_insn_and_split pattern. Adjust split
condition to split after epilogue_completed.
(popcounthi2): New insn pattern.
2016-12-16 Kelvin Nilsen <kelvin@gcc.gnu.org> 2016-12-16 Kelvin Nilsen <kelvin@gcc.gnu.org>
* config/rs6000/altivec.md (UNSPEC_CMPRB): New unspec value. * config/rs6000/altivec.md (UNSPEC_CMPRB): New unspec value.
...@@ -20,7 +44,7 @@ ...@@ -20,7 +44,7 @@
(CMPRB2): Add overload support for byte-in-either-range function. (CMPRB2): Add overload support for byte-in-either-range function.
(CMPEQB): Add overload support for byte-in-set built-in function. (CMPEQB): Add overload support for byte-in-set built-in function.
* config/rs6000/rs6000-c.c (P9_BUILTIN_CMPRB): Macro expansion to * config/rs6000/rs6000-c.c (P9_BUILTIN_CMPRB): Macro expansion to
define argument types for new builtin. define argument types for new builtin.
(P9_BUILTIN_CMPRB2): Likewise. (P9_BUILTIN_CMPRB2): Likewise.
(P9_BUILTIN_CMPEQB): Likewise. (P9_BUILTIN_CMPEQB): Likewise.
* doc/extend.texi (PowerPC AltiVec Built-in Functions): Rearrange * doc/extend.texi (PowerPC AltiVec Built-in Functions): Rearrange
...@@ -421,9 +445,9 @@ ...@@ -421,9 +445,9 @@
* arm-opts.h (struct arm_arch_core_flag): Add new field ISA. * arm-opts.h (struct arm_arch_core_flag): Add new field ISA.
Initialize it. Initialize it.
(arm_arch_core_flag): Delete flags field. (arm_arch_core_flag): Delete flags field.
(arm_arch_core_flags): Don't initialize flags field. (arm_arch_core_flags): Don't initialize flags field.
* common/config/arm/arm-common.c (check_isa_bits_for): New function. * common/config/arm/arm-common.c (check_isa_bits_for): New function.
(arm_target_thumb_only): Use new isa bits arrays. (arm_target_thumb_only): Use new isa bits arrays.
2016-12-15 Richard Earnshaw <rearnsha@arm.com> 2016-12-15 Richard Earnshaw <rearnsha@arm.com>
...@@ -5174,9 +5174,8 @@ ...@@ -5174,9 +5174,8 @@
(define_split (define_split
[(set (match_operand:MODEF 0 "sse_reg_operand") [(set (match_operand:MODEF 0 "sse_reg_operand")
(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))] (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
"TARGET_SSE_PARTIAL_REG_DEPENDENCY "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
&& optimize_function_for_speed_p (cfun) && optimize_function_for_speed_p (cfun)
&& epilogue_completed
&& (!EXT_REX_SSE_REG_P (operands[0]) && (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)" || TARGET_AVX512VL)"
[(set (match_dup 0) [(set (match_dup 0)
...@@ -5201,9 +5200,8 @@ ...@@ -5201,9 +5200,8 @@
[(set (match_operand:SF 0 "sse_reg_operand") [(set (match_operand:SF 0 "sse_reg_operand")
(float_truncate:SF (float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand")))] (match_operand:DF 1 "nonimmediate_operand")))]
"TARGET_SSE_PARTIAL_REG_DEPENDENCY "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
&& optimize_function_for_speed_p (cfun) && optimize_function_for_speed_p (cfun)
&& epilogue_completed
&& (!REG_P (operands[1]) && (!REG_P (operands[1])
|| REGNO (operands[0]) != REGNO (operands[1])) || REGNO (operands[0]) != REGNO (operands[1]))
&& (!EXT_REX_SSE_REG_P (operands[0]) && (!EXT_REX_SSE_REG_P (operands[0])
...@@ -5228,9 +5226,8 @@ ...@@ -5228,9 +5226,8 @@
[(set (match_operand:DF 0 "sse_reg_operand") [(set (match_operand:DF 0 "sse_reg_operand")
(float_extend:DF (float_extend:DF
(match_operand:SF 1 "nonimmediate_operand")))] (match_operand:SF 1 "nonimmediate_operand")))]
"TARGET_SSE_PARTIAL_REG_DEPENDENCY "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
&& optimize_function_for_speed_p (cfun) && optimize_function_for_speed_p (cfun)
&& epilogue_completed
&& (!REG_P (operands[1]) && (!REG_P (operands[1])
|| REGNO (operands[0]) != REGNO (operands[1])) || REGNO (operands[0]) != REGNO (operands[1]))
&& (!EXT_REX_SSE_REG_P (operands[0]) && (!EXT_REX_SSE_REG_P (operands[0])
...@@ -12569,54 +12566,43 @@ ...@@ -12569,54 +12566,43 @@
ix86_expand_clear (operands[2]); ix86_expand_clear (operands[2]);
}) })
; False dependency happens when destination is only updated by tzcnt, (define_insn_and_split "*tzcnt<mode>_1"
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn_and_split "*tzcnt<mode>_1_falsedep_1"
[(set (reg:CCC FLAGS_REG) [(set (reg:CCC FLAGS_REG)
(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
(const_int 0))) (const_int 0)))
(set (match_operand:SWI48 0 "register_operand" "=r") (set (match_operand:SWI48 0 "register_operand" "=r")
(ctz:SWI48 (match_dup 1)))] (ctz:SWI48 (match_dup 1)))]
"TARGET_BMI "TARGET_BMI"
&& TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
"#" "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
"&& reload_completed" && optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel [(parallel
[(set (reg:CCC FLAGS_REG) [(set (reg:CCC FLAGS_REG)
(compare:CCC (match_dup 1) (const_int 0))) (compare:CCC (match_dup 1) (const_int 0)))
(set (match_dup 0) (set (match_dup 0)
(ctz:SWI48 (match_dup 1))) (ctz:SWI48 (match_dup 1)))
(unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
{ "ix86_expand_clear (operands[0]);"
if (!reg_mentioned_p (operands[0], operands[1]))
ix86_expand_clear (operands[0]);
})
(define_insn "*tzcnt<mode>_1_falsedep"
[(set (reg:CCC FLAGS_REG)
(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
(const_int 0)))
(set (match_operand:SWI48 0 "register_operand" "=r")
(ctz:SWI48 (match_dup 1)))
(unspec [(match_operand:SWI48 2 "register_operand" "0")]
UNSPEC_INSN_FALSE_DEP)]
"TARGET_BMI"
"tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
[(set_attr "type" "alu1") [(set_attr "type" "alu1")
(set_attr "prefix_0f" "1") (set_attr "prefix_0f" "1")
(set_attr "prefix_rep" "1") (set_attr "prefix_rep" "1")
(set_attr "btver2_decode" "double") (set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*tzcnt<mode>_1" ; False dependency happens when destination is only updated by tzcnt,
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn "*tzcnt<mode>_1_falsedep"
[(set (reg:CCC FLAGS_REG) [(set (reg:CCC FLAGS_REG)
(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
(const_int 0))) (const_int 0)))
(set (match_operand:SWI48 0 "register_operand" "=r") (set (match_operand:SWI48 0 "register_operand" "=r")
(ctz:SWI48 (match_dup 1)))] (ctz:SWI48 (match_dup 1)))
(unspec [(match_operand:SWI48 2 "register_operand" "0")]
UNSPEC_INSN_FALSE_DEP)]
"TARGET_BMI" "TARGET_BMI"
"tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
[(set_attr "type" "alu1") [(set_attr "type" "alu1")
(set_attr "prefix_0f" "1") (set_attr "prefix_0f" "1")
(set_attr "prefix_rep" "1") (set_attr "prefix_rep" "1")
...@@ -12637,13 +12623,6 @@ ...@@ -12637,13 +12623,6 @@
(set_attr "znver1_decode" "vector") (set_attr "znver1_decode" "vector")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_expand "ctz<mode>2"
[(parallel
[(set (match_operand:SWI48 0 "register_operand")
(ctz:SWI48
(match_operand:SWI48 1 "nonimmediate_operand")))
(clobber (reg:CC FLAGS_REG))])])
(define_insn_and_split "*ctzhi2" (define_insn_and_split "*ctzhi2"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(ctz:SI (ctz:SI
...@@ -12662,28 +12641,47 @@ ...@@ -12662,28 +12641,47 @@
DONE; DONE;
}) })
; False dependency happens when destination is only updated by tzcnt, (define_insn_and_split "ctz<mode>2"
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn_and_split "*ctz<mode>2_falsedep_1"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(ctz:SWI48 (ctz:SWI48
(match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
""
{
if (TARGET_BMI)
return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
else if (optimize_function_for_size_p (cfun))
;
else if (TARGET_GENERIC)
/* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
}
"(TARGET_BMI || TARGET_GENERIC) "(TARGET_BMI || TARGET_GENERIC)
&& TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
"#" && optimize_function_for_speed_p (cfun)
"&& reload_completed" && !reg_mentioned_p (operands[0], operands[1])"
[(parallel [(parallel
[(set (match_dup 0) [(set (match_dup 0)
(ctz:SWI48 (match_dup 1))) (ctz:SWI48 (match_dup 1)))
(unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
{ "ix86_expand_clear (operands[0]);"
if (!reg_mentioned_p (operands[0], operands[1])) [(set_attr "type" "alu1")
ix86_expand_clear (operands[0]); (set_attr "prefix_0f" "1")
}) (set (attr "prefix_rep")
(if_then_else
(ior (match_test "TARGET_BMI")
(and (not (match_test "optimize_function_for_size_p (cfun)"))
(match_test "TARGET_GENERIC")))
(const_string "1")
(const_string "0")))
(set_attr "mode" "<MODE>")])
; False dependency happens when destination is only updated by tzcnt,
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn "*ctz<mode>2_falsedep" (define_insn "*ctz<mode>2_falsedep"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(ctz:SWI48 (ctz:SWI48
...@@ -12706,33 +12704,6 @@ ...@@ -12706,33 +12704,6 @@
(set_attr "prefix_rep" "1") (set_attr "prefix_rep" "1")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*ctz<mode>2"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))]
""
{
if (TARGET_BMI)
return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
else if (optimize_function_for_size_p (cfun))
;
else if (TARGET_GENERIC)
/* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
}
[(set_attr "type" "alu1")
(set_attr "prefix_0f" "1")
(set (attr "prefix_rep")
(if_then_else
(ior (match_test "TARGET_BMI")
(and (not (match_test "optimize_function_for_size_p (cfun)"))
(match_test "TARGET_GENERIC")))
(const_string "1")
(const_string "0")))
(set_attr "mode" "<MODE>")])
(define_insn "bsr_rex64" (define_insn "bsr_rex64"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (const_int 63) (minus:DI (const_int 63)
...@@ -12807,45 +12778,35 @@ ...@@ -12807,45 +12778,35 @@
DONE; DONE;
}) })
; False dependency happens when destination is only updated by tzcnt, (define_insn_and_split "clz<mode>2_lzcnt"
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(clz:SWI48 (clz:SWI48
(match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"TARGET_LZCNT "TARGET_LZCNT"
&& TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
"#" "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
"&& reload_completed" && optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel [(parallel
[(set (match_dup 0) [(set (match_dup 0)
(clz:SWI48 (match_dup 1))) (clz:SWI48 (match_dup 1)))
(unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
{ "ix86_expand_clear (operands[0]);"
if (!reg_mentioned_p (operands[0], operands[1]))
ix86_expand_clear (operands[0]);
})
(define_insn "*clz<mode>2_lzcnt_falsedep"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(clz:SWI48
(match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(unspec [(match_operand:SWI48 2 "register_operand" "0")]
UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))]
"TARGET_LZCNT"
"lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "prefix_rep" "1") [(set_attr "prefix_rep" "1")
(set_attr "type" "bitmanip") (set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "clz<mode>2_lzcnt" ; False dependency happens when destination is only updated by tzcnt,
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn "*clz<mode>2_lzcnt_falsedep"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(clz:SWI48 (clz:SWI48
(match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(unspec [(match_operand:SWI48 2 "register_operand" "0")]
UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"TARGET_LZCNT" "TARGET_LZCNT"
"lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
...@@ -12868,34 +12829,30 @@ ...@@ -12868,34 +12829,30 @@
;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
;; provides operand size as output when source operand is zero. ;; provides operand size as output when source operand is zero.
(define_expand "<lt_zcnt>_<mode>" (define_insn_and_split "<lt_zcnt>_<mode>"
[(parallel
[(set (match_operand:SWI248 0 "register_operand")
(unspec:SWI248
[(match_operand:SWI248 1 "nonimmediate_operand")] LT_ZCNT))
(clobber (reg:CC FLAGS_REG))])])
; False dependency happens when destination is only updated by tzcnt,
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn_and_split "*<lt_zcnt>_<mode>_falsedep_1"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(unspec:SWI48 (unspec:SWI48
[(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" ""
"#" "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
"&& reload_completed" "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
&& optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel [(parallel
[(set (match_dup 0) [(set (match_dup 0)
(unspec:SWI48 [(match_dup 1)] LT_ZCNT)) (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
(unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
{ "ix86_expand_clear (operands[0]);"
if (!reg_mentioned_p (operands[0], operands[1])) [(set_attr "type" "<lt_zcnt_type>")
ix86_expand_clear (operands[0]); (set_attr "prefix_0f" "1")
}) (set_attr "prefix_rep" "1")
(set_attr "mode" "<MODE>")])
; False dependency happens when destination is only updated by tzcnt,
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn "*<lt_zcnt>_<mode>_falsedep" (define_insn "*<lt_zcnt>_<mode>_falsedep"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(unspec:SWI48 (unspec:SWI48
...@@ -12910,17 +12867,17 @@ ...@@ -12910,17 +12867,17 @@
(set_attr "prefix_rep" "1") (set_attr "prefix_rep" "1")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*<lt_zcnt>_<mode>" (define_insn "<lt_zcnt>_hi"
[(set (match_operand:SWI248 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
(unspec:SWI248 (unspec:HI
[(match_operand:SWI248 1 "nonimmediate_operand" "rm")] LT_ZCNT)) [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"" ""
"<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
[(set_attr "type" "<lt_zcnt_type>") [(set_attr "type" "<lt_zcnt_type>")
(set_attr "prefix_0f" "1") (set_attr "prefix_0f" "1")
(set_attr "prefix_rep" "1") (set_attr "prefix_rep" "1")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "HI")])
;; BMI instructions. ;; BMI instructions.
...@@ -13216,33 +13173,35 @@ ...@@ -13216,33 +13173,35 @@
[(set_attr "type" "bitmanip") [(set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_expand "popcount<mode>2" (define_insn_and_split "popcount<mode>2"
[(parallel
[(set (match_operand:SWI248 0 "register_operand")
(popcount:SWI248
(match_operand:SWI248 1 "nonimmediate_operand")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_POPCNT")
(define_insn_and_split "*popcount<mode>2_falsedep_1"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(popcount:SWI48 (popcount:SWI48
(match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"TARGET_POPCNT "TARGET_POPCNT"
&& TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" {
"#" #if TARGET_MACHO
"&& reload_completed" return "popcnt\t{%1, %0|%0, %1}";
#else
return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
#endif
}
"&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
&& optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel [(parallel
[(set (match_dup 0) [(set (match_dup 0)
(popcount:SWI48 (match_dup 1))) (popcount:SWI48 (match_dup 1)))
(unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
{ "ix86_expand_clear (operands[0]);"
if (!reg_mentioned_p (operands[0], operands[1])) [(set_attr "prefix_rep" "1")
ix86_expand_clear (operands[0]); (set_attr "type" "bitmanip")
}) (set_attr "mode" "<MODE>")])
; False dependency happens when destination is only updated by tzcnt,
; lzcnt or popcnt. There is no false dependency when destination is
; also used in source.
(define_insn "*popcount<mode>2_falsedep" (define_insn "*popcount<mode>2_falsedep"
[(set (match_operand:SWI48 0 "register_operand" "=r") [(set (match_operand:SWI48 0 "register_operand" "=r")
(popcount:SWI48 (popcount:SWI48
...@@ -13262,22 +13221,22 @@ ...@@ -13262,22 +13221,22 @@
(set_attr "type" "bitmanip") (set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*popcount<mode>2" (define_insn "popcounthi2"
[(set (match_operand:SWI248 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
(popcount:SWI248 (popcount:HI
(match_operand:SWI248 1 "nonimmediate_operand" "rm"))) (match_operand:HI 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"TARGET_POPCNT" "TARGET_POPCNT"
{ {
#if TARGET_MACHO #if TARGET_MACHO
return "popcnt\t{%1, %0|%0, %1}"; return "popcnt\t{%1, %0|%0, %1}";
#else #else
return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; return "popcnt{w}\t{%1, %0|%0, %1}";
#endif #endif
} }
[(set_attr "prefix_rep" "1") [(set_attr "prefix_rep" "1")
(set_attr "type" "bitmanip") (set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "HI")])
(define_expand "bswapdi2" (define_expand "bswapdi2"
[(set (match_operand:DI 0 "register_operand") [(set (match_operand:DI 0 "register_operand")
......
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