diff options
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r-- | gcc/config/i386/i386.md | 79 |
1 files changed, 75 insertions, 4 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index eff96a106d4..a4881f5e6fb 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -229,6 +229,9 @@ UNSPEC_VTESTP UNSPEC_VCVTPH2PS UNSPEC_VCVTPS2PH + + ;; For BMI support + UNSPEC_BEXTR ]) (define_c_enum "unspecv" [ @@ -11988,13 +11991,19 @@ (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"))) + [(set (match_operand:SWI248 0 "register_operand" "=r") + (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "" - "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" +{ + if (TARGET_BMI) + return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; + else + return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; +} [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") + (set (attr "prefix_rep") (symbol_ref "TARGET_BMI")) (set_attr "mode" "<MODE>")]) (define_expand "clz<mode>2" @@ -12021,12 +12030,74 @@ [(set (match_operand:SWI248 0 "register_operand" "=r") (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] - "TARGET_ABM" + "TARGET_ABM || TARGET_BMI" "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" [(set_attr "prefix_rep" "1") (set_attr "type" "bitmanip") (set_attr "mode" "<MODE>")]) +;; BMI instructions. +(define_insn "*bmi_andn_<mode>" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (and:SWI48 + (not:SWI48 + (match_operand:SWI48 1 "register_operand" "r")) + (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_BMI" + "andn\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "<MODE>")]) + +(define_insn "bmi_bextr_<mode>" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm") + (match_operand:SWI48 2 "register_operand" "r")] + UNSPEC_BEXTR)) + (clobber (reg:CC FLAGS_REG))] + "TARGET_BMI" + "bextr\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "<MODE>")]) + +(define_insn "*bmi_blsi_<mode>" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (and:SWI48 + (neg:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm")) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_BMI" + "blsi\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "<MODE>")]) + +(define_insn "*bmi_blsmsk_<mode>" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (xor:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int -1)) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_BMI" + "blsmsk\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "<MODE>")]) + +(define_insn "*bmi_blsr_<mode>" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (and:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int -1)) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_BMI" + "blsr\t{%1, %0|%0, %1}" + [(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) |