DONE;
}
- flags_mode
- = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
+ flags_mode = TARGET_BMI ? CCCmode : CCZmode;
operands[2] = gen_reg_rtx (<MODE>mode);
operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
(clobber (reg:CC FLAGS_REG))])]
{
- machine_mode flags_mode
- = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
+ machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
operands[3] = gen_lowpart (QImode, operands[2]);
operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
ix86_expand_clear (operands[2]);
})
+; 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 "*tzcnt<mode>_1_falsedep_1"
+ [(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)))]
+ "TARGET_BMI
+ && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC (match_dup 1) (const_int 0)))
+ (set (match_dup 0)
+ (ctz:SWI48 (match_dup 1)))
+ (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
+{
+ 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 "prefix_0f" "1")
+ (set_attr "prefix_rep" "1")
+ (set_attr "btver2_decode" "double")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*tzcnt<mode>_1"
[(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)))]
- "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
+ "TARGET_BMI"
"tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")
(set_attr "prefix_0f" "1")
{
rtx tmp = gen_reg_rtx (HImode);
- emit_insn (gen_bmi_tzcnt_hi (tmp, operands[1]));
+ emit_insn (gen_tzcnt_hi (tmp, operands[1]));
emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
DONE;
})
(const_string "0")))
(set_attr "mode" "<MODE>")])
-;; Version of tzcnt that is expanded from intrinsics. This version provides
-;; operand size as output when source operand is zero.
-
-(define_expand "bmi_tzcnt_<mode>"
- [(parallel
- [(set (match_operand:SWI248 0 "register_operand")
- (unspec:SWI248
- [(match_operand:SWI248 1 "nonimmediate_operand")]
- UNSPEC_TZCNT))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_BMI")
-
-; 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 "*bmi_tzcnt_<mode>_falsedep_1"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (unspec:SWI48
- [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
- UNSPEC_TZCNT))
+(define_insn "bsr_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:DI (const_int 63)
+ (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI
- && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
- "#"
- "&& reload_completed"
- [(parallel
- [(set (match_dup 0)
- (unspec:SWI48 [(match_dup 1)] UNSPEC_TZCNT))
- (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (!reg_mentioned_p (operands[0], operands[1]))
- ix86_expand_clear (operands[0]);
-})
+ "TARGET_64BIT"
+ "bsr{q}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "znver1_decode" "vector")
+ (set_attr "mode" "DI")])
-(define_insn "*bmi_tzcnt_<mode>_falsedep"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (unspec:SWI48
- [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
- UNSPEC_TZCNT))
- (unspec [(match_operand:SWI48 2 "register_operand" "0")]
- UNSPEC_INSN_FALSE_DEP)
+(define_insn "bsr"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (minus:SI (const_int 31)
+ (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
+ ""
+ "bsr{l}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")
(set_attr "prefix_0f" "1")
- (set_attr "prefix_rep" "1")
- (set_attr "mode" "<MODE>")])
+ (set_attr "znver1_decode" "vector")
+ (set_attr "mode" "SI")])
-(define_insn "*bmi_tzcnt_<mode>"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (unspec:SWI248
- [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
- UNSPEC_TZCNT))
+(define_insn "*bsrhi"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (const_int 15)
+ (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
+ ""
+ "bsr{w}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")
(set_attr "prefix_0f" "1")
- (set_attr "prefix_rep" "1")
- (set_attr "mode" "<MODE>")])
+ (set_attr "znver1_decode" "vector")
+ (set_attr "mode" "HI")])
(define_expand "clz<mode>2"
[(parallel
operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
})
-(define_expand "clz<mode>2_lzcnt"
- [(parallel
- [(set (match_operand:SWI48 0 "register_operand")
- (clz:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_LZCNT")
-
(define_insn_and_split "*clzhi2"
[(set (match_operand:SI 0 "register_operand")
(clz:SI
(set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")])
-(define_insn "*clz<mode>2_lzcnt"
+(define_insn "clz<mode>2_lzcnt"
[(set (match_operand:SWI48 0 "register_operand" "=r")
- (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
+ (clz:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_LZCNT"
"lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
(set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")])
-;; Version of lzcnt that is expanded from intrinsics. This version provides
-;; operand size as output when source operand is zero.
+(define_int_iterator LT_ZCNT
+ [(UNSPEC_TZCNT "TARGET_BMI")
+ (UNSPEC_LZCNT "TARGET_LZCNT")])
+
+(define_int_attr lt_zcnt
+ [(UNSPEC_TZCNT "tzcnt")
+ (UNSPEC_LZCNT "lzcnt")])
+
+(define_int_attr lt_zcnt_type
+ [(UNSPEC_TZCNT "alu1")
+ (UNSPEC_LZCNT "bitmanip")])
-(define_expand "lzcnt_<mode>"
+;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
+;; provides operand size as output when source operand is zero.
+
+(define_expand "<lt_zcnt>_<mode>"
[(parallel
[(set (match_operand:SWI248 0 "register_operand")
(unspec:SWI248
- [(match_operand:SWI248 1 "nonimmediate_operand")]
- UNSPEC_LZCNT))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_LZCNT")
+ [(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 "*lzcnt_<mode>_falsedep_1"
+(define_insn_and_split "*<lt_zcnt>_<mode>_falsedep_1"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(unspec:SWI48
- [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
- UNSPEC_LZCNT))
+ [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_LZCNT
- && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
+ "TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
"#"
"&& reload_completed"
[(parallel
[(set (match_dup 0)
- (unspec:SWI48 [(match_dup 1)] UNSPEC_LZCNT))
+ (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
(unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
(clobber (reg:CC FLAGS_REG))])]
{
ix86_expand_clear (operands[0]);
})
-(define_insn "*lzcnt_<mode>_falsedep"
+(define_insn "*<lt_zcnt>_<mode>_falsedep"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(unspec:SWI48
- [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
- UNSPEC_LZCNT))
+ [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
(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 "type" "alu1")
+ ""
+ "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "<lt_zcnt_type>")
(set_attr "prefix_0f" "1")
(set_attr "prefix_rep" "1")
(set_attr "mode" "<MODE>")])
-(define_insn "*lzcnt_<mode>"
+(define_insn "*<lt_zcnt>_<mode>"
[(set (match_operand:SWI248 0 "register_operand" "=r")
(unspec:SWI248
- [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
- UNSPEC_LZCNT))
+ [(match_operand:SWI248 1 "nonimmediate_operand" "rm")] LT_ZCNT))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_LZCNT"
- "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
+ ""
+ "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "<lt_zcnt_type>")
(set_attr "prefix_0f" "1")
(set_attr "prefix_rep" "1")
(set_attr "mode" "<MODE>")])
[(set_attr "type" "bitmanip")
(set_attr "mode" "<MODE>")])
-(define_insn "bsr_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (const_int 63)
- (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "bsr{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "znver1_decode" "vector")
- (set_attr "mode" "DI")])
-
-(define_insn "bsr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (const_int 31)
- (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "bsr{l}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "znver1_decode" "vector")
- (set_attr "mode" "SI")])
-
-(define_insn "*bsrhi"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (minus:HI (const_int 15)
- (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "bsr{w}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "znver1_decode" "vector")
- (set_attr "mode" "HI")])
-
(define_expand "popcount<mode>2"
[(parallel
[(set (match_operand:SWI248 0 "register_operand")