From: Uros Bizjak Date: Tue, 14 May 2019 16:18:06 +0000 (+0200) Subject: i386.md (any_div): New code iterator. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=00f0898d2f11c54cfe39e497ec3f60235483a839;p=gcc.git i386.md (any_div): New code iterator. * config/i386/i386.md (any_div): New code iterator. (paired_mod): New code attribute. (sgnprefix): Handle DIV and UDIV RTXes. (u): Ditto. (divmod4): Macroize expander from divmod4 and udivmod4 patterns using any_div code iterator. (divmod splitters): Macroize splitters using any_div code iterator. (*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition. (*udivmodsi4_pow2_zext_2): Ditto. (*divmod4_noext): Macroize insn from *divmod4_noext and *udivmod4_noext patterns using any_div code iterator. (*divmod4_noext_zext_1): Macroize insn from *divmod4_noext_zext_1 and *udivmod4_noext_zext_1 patterns using any_div code iterator. (*divmod4_noext_zext_2): Macroize insn from *divmod4_noext_zext_2 and *udivmod4_noext_zext_2 patterns using any_div code iterator. (divmodhiqi3): Macroize insn from divmodhiqi3 and udivmodhiqi3 patterns using any_extend code iterator. From-SVN: r271179 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1af0304076a..0e7bce8a46d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,12 +1,34 @@ +2019-05-14 Uroš Bizjak + + * config/i386/i386.md (any_div): New code iterator. + (paired_mod): New code attribute. + (sgnprefix): Handle DIV and UDIV RTXes. + (u): Ditto. + (divmod4): Macroize expander from divmod4 + and udivmod4 patterns using any_div code iterator. + (divmod splitters): Macroize splitters using any_div code iterator. + (*udivmodsi4_pow2_zext_1): Use exactl_log2 in insn condition. + (*udivmodsi4_pow2_zext_2): Ditto. + (*divmod4_noext): Macroize insn from *divmod4_noext + and *udivmod4_noext patterns using any_div code iterator. + (*divmod4_noext_zext_1): Macroize insn from + *divmod4_noext_zext_1 and *udivmod4_noext_zext_1 + patterns using any_div code iterator. + (*divmod4_noext_zext_2): Macroize insn from + *divmod4_noext_zext_2 and *udivmod4_noext_zext_2 + patterns using any_div code iterator. + (divmodhiqi3): Macroize insn from divmodhiqi3 and + udivmodhiqi3 patterns using any_extend code iterator. + 2019-05-14 Richard Biener - H.J. Lu + H.J. Lu PR tree-optimization/88828 * tree-ssa-forwprop.c (simplify_vector_constructor): Handle permuting in a single non-constant element not extracted from a vector. -2019-05-14 Przemyslaw Wirkus +2019-05-14 Przemyslaw Wirkus * internal-fn.def (SIGNBIT): New. * config/aarch64/aarch64-simd.md (signbitv2sf2): New expand diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index edec0ab0386..05411221197 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -933,11 +933,12 @@ (define_code_iterator any_extend [sign_extend zero_extend]) ;; Prefix for insn menmonic. -(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) - +(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "") + (div "i") (udiv "")]) ;; Prefix for define_insn -(define_code_attr u [(sign_extend "") (zero_extend "u")]) (define_code_attr s [(sign_extend "s") (zero_extend "u")]) +(define_code_attr u [(sign_extend "") (zero_extend "u") + (div "") (udiv "u")]) (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")]) ;; Used in signed and unsigned truncations. @@ -7475,13 +7476,16 @@ ;; Divmod instructions. -(define_expand "divmod4" +(define_code_iterator any_div [div udiv]) +(define_code_attr paired_mod [(div "mod") (udiv "umod")]) + +(define_expand "divmod4" [(parallel [(set (match_operand:SWIM248 0 "register_operand") - (div:SWIM248 + (any_div:SWIM248 (match_operand:SWIM248 1 "register_operand") (match_operand:SWIM248 2 "nonimmediate_operand"))) (set (match_operand:SWIM248 3 "register_operand") - (mod:SWIM248 (match_dup 1) (match_dup 2))) + (:SWIM248 (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])]) ;; Split with 8bit unsigned divide: @@ -7491,10 +7495,10 @@ ;; use original integer divide (define_split [(set (match_operand:SWI48 0 "register_operand") - (div:SWI48 (match_operand:SWI48 2 "register_operand") - (match_operand:SWI48 3 "nonimmediate_operand"))) + (any_div:SWI48 (match_operand:SWI48 2 "register_operand") + (match_operand:SWI48 3 "nonimmediate_operand"))) (set (match_operand:SWI48 1 "register_operand") - (mod:SWI48 (match_dup 2) (match_dup 3))) + (:SWI48 (match_dup 2) (match_dup 3))) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_8BIT_IDIV && TARGET_QIMODE_MATH @@ -7506,12 +7510,13 @@ (define_split [(set (match_operand:DI 0 "register_operand") (zero_extend:DI - (div:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) + (any_div:SI (match_operand:SI 2 "register_operand") + (match_operand:SI 3 "nonimmediate_operand")))) (set (match_operand:SI 1 "register_operand") - (mod:SI (match_dup 2) (match_dup 3))) + (:SI (match_dup 2) (match_dup 3))) (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_8BIT_IDIV + "TARGET_64BIT + && TARGET_USE_8BIT_IDIV && TARGET_QIMODE_MATH && can_create_pseudo_p () && !optimize_insn_for_size_p ()" @@ -7521,12 +7526,13 @@ (define_split [(set (match_operand:DI 1 "register_operand") (zero_extend:DI - (mod:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) + (:SI (match_operand:SI 2 "register_operand") + (match_operand:SI 3 "nonimmediate_operand")))) (set (match_operand:SI 0 "register_operand") - (div:SI (match_dup 2) (match_dup 3))) + (any_div:SI (match_dup 2) (match_dup 3))) (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_8BIT_IDIV + "TARGET_64BIT + && TARGET_USE_8BIT_IDIV && TARGET_QIMODE_MATH && can_create_pseudo_p () && !optimize_insn_for_size_p ()" @@ -7568,6 +7574,28 @@ [(set_attr "type" "multi") (set_attr "mode" "")]) +(define_insn_and_split "udivmod4_1" + [(set (match_operand:SWI48 0 "register_operand" "=a") + (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") + (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) + (set (match_operand:SWI48 1 "register_operand" "=&d") + (umod:SWI48 (match_dup 2) (match_dup 3))) + (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) + (clobber (reg:CC FLAGS_REG))] + "" + "#" + "reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (udiv:SWI48 (match_dup 2) (match_dup 3))) + (set (match_dup 1) + (umod:SWI48 (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "")]) + (define_insn_and_split "divmodsi4_zext_1" [(set (match_operand:DI 0 "register_operand" "=a") (zero_extend:DI @@ -7579,7 +7607,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7604,6 +7632,29 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) +(define_insn_and_split "udivmodsi4_zext_1" + [(set (match_operand:DI 0 "register_operand" "=a") + (zero_extend:DI + (udiv:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 1 "register_operand" "=&d") + (umod:SI (match_dup 2) (match_dup 3))) + (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 1) + (umod:SI (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + (define_insn_and_split "divmodsi4_zext_2" [(set (match_operand:DI 1 "register_operand" "=&d") (zero_extend:DI @@ -7615,7 +7666,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 6) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7641,6 +7692,29 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) +(define_insn_and_split "udivmodsi4_zext_2" + [(set (match_operand:DI 1 "register_operand" "=&d") + (zero_extend:DI + (umod:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 0 "register_operand" "=a") + (udiv:SI (match_dup 2) (match_dup 3))) + (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 4) (const_int 0)) + (parallel [(set (match_dup 1) + (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 0) + (udiv:SI (match_dup 2) (match_dup 3))) + (use (match_dup 4)) + (clobber (reg:CC FLAGS_REG))])] + "operands[4] = gen_lowpart (SImode, operands[1]);" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + (define_insn_and_split "*divmod4" [(set (match_operand:SWIM248 0 "register_operand" "=a") (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") @@ -7676,6 +7750,52 @@ [(set_attr "type" "multi") (set_attr "mode" "")]) +(define_insn_and_split "*udivmod4" + [(set (match_operand:SWIM248 0 "register_operand" "=a") + (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") + (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) + (set (match_operand:SWIM248 1 "register_operand" "=&d") + (umod:SWIM248 (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "" + "#" + "reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (udiv:SWIM248 (match_dup 2) (match_dup 3))) + (set (match_dup 1) + (umod:SWIM248 (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "")]) + +;; Optimize division or modulo by constant power of 2, if the constant +;; materializes only after expansion. +(define_insn_and_split "*udivmod4_pow2" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") + (match_operand:SWI48 3 "const_int_operand" "n"))) + (set (match_operand:SWI48 1 "register_operand" "=r") + (umod:SWI48 (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)" + "#" + "&& reload_completed" + [(set (match_dup 1) (match_dup 2)) + (parallel [(set (match_dup 0) (lshiftrt: (match_dup 2) (match_dup 4))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 1) (and: (match_dup 1) (match_dup 5))) + (clobber (reg:CC FLAGS_REG))])] +{ + int v = exact_log2 (UINTVAL (operands[3])); + operands[4] = GEN_INT (v); + operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); +} + [(set_attr "type" "multi") + (set_attr "mode" "")]) + (define_insn_and_split "*divmodsi4_zext_1" [(set (match_operand:DI 0 "register_operand" "=a") (zero_extend:DI @@ -7686,7 +7806,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7711,6 +7831,54 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) +(define_insn_and_split "*udivmodsi4_zext_1" + [(set (match_operand:DI 0 "register_operand" "=a") + (zero_extend:DI + (udiv:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 1 "register_operand" "=&d") + (umod:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 1) (const_int 0)) + (parallel [(set (match_dup 0) + (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 1) + (umod:SI (match_dup 2) (match_dup 3))) + (use (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + +(define_insn_and_split "*udivmodsi4_pow2_zext_1" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (udiv:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "const_int_operand" "n")))) + (set (match_operand:SI 1 "register_operand" "=r") + (umod:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && exact_log2 (UINTVAL (operands[3])) > 0" + "#" + "&& reload_completed" + [(set (match_dup 1) (match_dup 2)) + (parallel [(set (match_dup 0) + (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4)))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5))) + (clobber (reg:CC FLAGS_REG))])] +{ + int v = exact_log2 (UINTVAL (operands[3])); + operands[4] = GEN_INT (v); + operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); +} + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + (define_insn_and_split "*divmodsi4_zext_2" [(set (match_operand:DI 1 "register_operand" "=&d") (zero_extend:DI @@ -7721,7 +7889,7 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "#" - "reload_completed" + "&& reload_completed" [(parallel [(set (match_dup 6) (ashiftrt:SI (match_dup 4) (match_dup 5))) (clobber (reg:CC FLAGS_REG))]) @@ -7747,44 +7915,93 @@ [(set_attr "type" "multi") (set_attr "mode" "SI")]) -(define_insn "*divmod4_noext" +(define_insn_and_split "*udivmodsi4_zext_2" + [(set (match_operand:DI 1 "register_operand" "=&d") + (zero_extend:DI + (umod:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (set (match_operand:SI 0 "register_operand" "=a") + (udiv:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 4) (const_int 0)) + (parallel [(set (match_dup 1) + (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) + (set (match_dup 0) + (udiv:SI (match_dup 2) (match_dup 3))) + (use (match_dup 4)) + (clobber (reg:CC FLAGS_REG))])] + "operands[4] = gen_lowpart (SImode, operands[1]);" + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + +(define_insn_and_split "*udivmodsi4_pow2_zext_2" + [(set (match_operand:DI 1 "register_operand" "=r") + (zero_extend:DI + (umod:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "const_int_operand" "n")))) + (set (match_operand:SI 0 "register_operand" "=r") + (umod:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && exact_log2 (UINTVAL (operands[3])) > 0" + "#" + "&& reload_completed" + [(set (match_dup 1) (match_dup 2)) + (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4))) + (clobber (reg:CC FLAGS_REG))]) + (parallel [(set (match_dup 1) + (zero_extend:DI (and:SI (match_dup 1) (match_dup 5)))) + (clobber (reg:CC FLAGS_REG))])] +{ + int v = exact_log2 (UINTVAL (operands[3])); + operands[4] = GEN_INT (v); + operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); +} + [(set_attr "type" "multi") + (set_attr "mode" "SI")]) + +(define_insn "*divmod4_noext" [(set (match_operand:SWIM248 0 "register_operand" "=a") - (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") - (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) + (any_div:SWIM248 + (match_operand:SWIM248 2 "register_operand" "0") + (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) (set (match_operand:SWIM248 1 "register_operand" "=d") - (mod:SWIM248 (match_dup 2) (match_dup 3))) + (:SWIM248 (match_dup 2) (match_dup 3))) (use (match_operand:SWIM248 4 "register_operand" "1")) (clobber (reg:CC FLAGS_REG))] "" - "idiv{}\t%3" + "div{}\t%3" [(set_attr "type" "idiv") (set_attr "mode" "")]) -(define_insn "*divmodsi4_noext_zext_1" +(define_insn "*divmodsi4_noext_zext_1" [(set (match_operand:DI 0 "register_operand" "=a") (zero_extend:DI - (div:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (any_div:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) (set (match_operand:SI 1 "register_operand" "=d") - (mod:SI (match_dup 2) (match_dup 3))) + (:SI (match_dup 2) (match_dup 3))) (use (match_operand:SI 4 "register_operand" "1")) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "idiv{l}\t%3" + "div{l}\t%3" [(set_attr "type" "idiv") (set_attr "mode" "SI")]) -(define_insn "*divmodsi4_noext_zext_2" +(define_insn "*divmodsi4_noext_zext_2" [(set (match_operand:DI 1 "register_operand" "=d") (zero_extend:DI - (mod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) + (:SI (match_operand:SI 2 "register_operand" "0") + (match_operand:SI 3 "nonimmediate_operand" "rm")))) (set (match_operand:SI 0 "register_operand" "=a") - (div:SI (match_dup 2) (match_dup 3))) + (any_div:SI (match_dup 2) (match_dup 3))) (use (match_operand:SI 4 "register_operand" "1")) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" - "idiv{l}\t%3" + "div{l}\t%3" [(set_attr "type" "idiv") (set_attr "mode" "SI")]) @@ -7800,7 +8017,7 @@ { rtx div, mod; rtx tmp0, tmp1; - + tmp0 = gen_reg_rtx (HImode); tmp1 = gen_reg_rtx (HImode); @@ -7825,345 +8042,6 @@ DONE; }) -;; Divide AX by r/m8, with result stored in -;; AL <- Quotient -;; AH <- Remainder -;; Change div/mod to HImode and extend the second argument to HImode -;; so that mode of div/mod matches with mode of arguments. Otherwise -;; combine may fail. -(define_insn "divmodhiqi3" - [(set (match_operand:HI 0 "register_operand" "=a") - (ior:HI - (ashift:HI - (zero_extend:HI - (truncate:QI - (mod:HI (match_operand:HI 1 "register_operand" "0") - (sign_extend:HI - (match_operand:QI 2 "nonimmediate_operand" "qm"))))) - (const_int 8)) - (zero_extend:HI - (truncate:QI - (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_QIMODE_MATH" - "idiv{b}\t%2" - [(set_attr "type" "idiv") - (set_attr "mode" "QI")]) - -(define_expand "udivmod4" - [(parallel [(set (match_operand:SWIM248 0 "register_operand") - (udiv:SWIM248 - (match_operand:SWIM248 1 "register_operand") - (match_operand:SWIM248 2 "nonimmediate_operand"))) - (set (match_operand:SWIM248 3 "register_operand") - (umod:SWIM248 (match_dup 1) (match_dup 2))) - (clobber (reg:CC FLAGS_REG))])]) - -;; Split with 8bit unsigned divide: -;; if (dividend an divisor are in [0-255]) -;; use 8bit unsigned integer divide -;; else -;; use original integer divide -(define_split - [(set (match_operand:SWI48 0 "register_operand") - (udiv:SWI48 (match_operand:SWI48 2 "register_operand") - (match_operand:SWI48 3 "nonimmediate_operand"))) - (set (match_operand:SWI48 1 "register_operand") - (umod:SWI48 (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_8BIT_IDIV - && TARGET_QIMODE_MATH - && can_create_pseudo_p () - && !optimize_insn_for_size_p ()" - [(const_int 0)] - "ix86_split_idivmod (mode, operands, false); DONE;") - -(define_split - [(set (match_operand:DI 0 "register_operand") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) - (set (match_operand:SI 1 "register_operand") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && TARGET_USE_8BIT_IDIV - && TARGET_QIMODE_MATH - && can_create_pseudo_p () - && !optimize_insn_for_size_p ()" - [(const_int 0)] - "ix86_split_idivmod (SImode, operands, false); DONE;") - -(define_split - [(set (match_operand:DI 1 "register_operand") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand") - (match_operand:SI 3 "nonimmediate_operand")))) - (set (match_operand:SI 0 "register_operand") - (udiv:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && TARGET_USE_8BIT_IDIV - && TARGET_QIMODE_MATH - && can_create_pseudo_p () - && !optimize_insn_for_size_p ()" - [(const_int 0)] - "ix86_split_idivmod (SImode, operands, false); DONE;") - -(define_insn_and_split "udivmod4_1" - [(set (match_operand:SWI48 0 "register_operand" "=a") - (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") - (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) - (set (match_operand:SWI48 1 "register_operand" "=&d") - (umod:SWI48 (match_dup 2) (match_dup 3))) - (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) - (clobber (reg:CC FLAGS_REG))] - "" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (udiv:SWI48 (match_dup 2) (match_dup 3))) - (set (match_dup 1) - (umod:SWI48 (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "")]) - -(define_insn_and_split "udivmodsi4_zext_1" - [(set (match_operand:DI 0 "register_operand" "=a") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 1 "register_operand" "=&d") - (umod:SI (match_dup 2) (match_dup 3))) - (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 1) - (umod:SI (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "udivmodsi4_zext_2" - [(set (match_operand:DI 1 "register_operand" "=&d") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_dup 2) (match_dup 3))) - (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 4) (const_int 0)) - (parallel [(set (match_dup 1) - (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 0) - (udiv:SI (match_dup 2) (match_dup 3))) - (use (match_dup 4)) - (clobber (reg:CC FLAGS_REG))])] - "operands[4] = gen_lowpart (SImode, operands[1]);" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "*udivmod4" - [(set (match_operand:SWIM248 0 "register_operand" "=a") - (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") - (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) - (set (match_operand:SWIM248 1 "register_operand" "=&d") - (umod:SWIM248 (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (udiv:SWIM248 (match_dup 2) (match_dup 3))) - (set (match_dup 1) - (umod:SWIM248 (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "")]) - -(define_insn_and_split "*udivmodsi4_zext_1" - [(set (match_operand:DI 0 "register_operand" "=a") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 1 "register_operand" "=&d") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 1) (const_int 0)) - (parallel [(set (match_dup 0) - (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 1) - (umod:SI (match_dup 2) (match_dup 3))) - (use (match_dup 1)) - (clobber (reg:CC FLAGS_REG))])] - "" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "*udivmodsi4_zext_2" - [(set (match_operand:DI 1 "register_operand" "=&d") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "#" - "reload_completed" - [(set (match_dup 4) (const_int 0)) - (parallel [(set (match_dup 1) - (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) - (set (match_dup 0) - (udiv:SI (match_dup 2) (match_dup 3))) - (use (match_dup 4)) - (clobber (reg:CC FLAGS_REG))])] - "operands[4] = gen_lowpart (SImode, operands[1]);" - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -;; Optimize division or modulo by constant power of 2, if the constant -;; materializes only after expansion. -(define_insn_and_split "*udivmod4_pow2" - [(set (match_operand:SWI48 0 "register_operand" "=r") - (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") - (match_operand:SWI48 3 "const_int_operand" "n"))) - (set (match_operand:SWI48 1 "register_operand" "=r") - (umod:SWI48 (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) - && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" - "#" - "&& 1" - [(set (match_dup 1) (match_dup 2)) - (parallel [(set (match_dup 0) (lshiftrt: (match_dup 2) (match_dup 4))) - (clobber (reg:CC FLAGS_REG))]) - (parallel [(set (match_dup 1) (and: (match_dup 1) (match_dup 5))) - (clobber (reg:CC FLAGS_REG))])] -{ - int v = exact_log2 (UINTVAL (operands[3])); - operands[4] = GEN_INT (v); - operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); -} - [(set_attr "type" "multi") - (set_attr "mode" "")]) - -(define_insn_and_split "*udivmodsi4_pow2_zext_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "const_int_operand" "n")))) - (set (match_operand:SI 1 "register_operand" "=r") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) - && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" - "#" - "&& 1" - [(set (match_dup 1) (match_dup 2)) - (parallel [(set (match_dup 0) - (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4)))) - (clobber (reg:CC FLAGS_REG))]) - (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5))) - (clobber (reg:CC FLAGS_REG))])] -{ - int v = exact_log2 (UINTVAL (operands[3])); - operands[4] = GEN_INT (v); - operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); -} - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn_and_split "*udivmodsi4_pow2_zext_2" - [(set (match_operand:DI 1 "register_operand" "=r") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "const_int_operand" "n")))) - (set (match_operand:SI 0 "register_operand" "=r") - (umod:SI (match_dup 2) (match_dup 3))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) - && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" - "#" - "&& 1" - [(set (match_dup 1) (match_dup 2)) - (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4))) - (clobber (reg:CC FLAGS_REG))]) - (parallel [(set (match_dup 1) - (zero_extend:DI (and:SI (match_dup 1) (match_dup 5)))) - (clobber (reg:CC FLAGS_REG))])] -{ - int v = exact_log2 (UINTVAL (operands[3])); - operands[4] = GEN_INT (v); - operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); -} - [(set_attr "type" "multi") - (set_attr "mode" "SI")]) - -(define_insn "*udivmod4_noext" - [(set (match_operand:SWIM248 0 "register_operand" "=a") - (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") - (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) - (set (match_operand:SWIM248 1 "register_operand" "=d") - (umod:SWIM248 (match_dup 2) (match_dup 3))) - (use (match_operand:SWIM248 4 "register_operand" "1")) - (clobber (reg:CC FLAGS_REG))] - "" - "div{}\t%3" - [(set_attr "type" "idiv") - (set_attr "mode" "")]) - -(define_insn "*udivmodsi4_noext_zext_1" - [(set (match_operand:DI 0 "register_operand" "=a") - (zero_extend:DI - (udiv:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 1 "register_operand" "=d") - (umod:SI (match_dup 2) (match_dup 3))) - (use (match_operand:SI 4 "register_operand" "1")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "div{l}\t%3" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_insn "*udivmodsi4_noext_zext_2" - [(set (match_operand:DI 1 "register_operand" "=d") - (zero_extend:DI - (umod:SI (match_operand:SI 2 "register_operand" "0") - (match_operand:SI 3 "nonimmediate_operand" "rm")))) - (set (match_operand:SI 0 "register_operand" "=a") - (udiv:SI (match_dup 2) (match_dup 3))) - (use (match_operand:SI 4 "register_operand" "1")) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "div{l}\t%3" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - (define_expand "udivmodqi4" [(parallel [(set (match_operand:QI 0 "register_operand") (udiv:QI @@ -8176,7 +8054,7 @@ { rtx div, mod; rtx tmp0, tmp1; - + tmp0 = gen_reg_rtx (HImode); tmp1 = gen_reg_rtx (HImode); @@ -8201,22 +8079,28 @@ DONE; }) -(define_insn "udivmodhiqi3" +;; Divide AX by r/m8, with result stored in +;; AL <- Quotient +;; AH <- Remainder +;; Change div/mod to HImode and extend the second argument to HImode +;; so that mode of div/mod matches with mode of arguments. Otherwise +;; combine may fail. +(define_insn "divmodhiqi3" [(set (match_operand:HI 0 "register_operand" "=a") (ior:HI (ashift:HI (zero_extend:HI (truncate:QI (mod:HI (match_operand:HI 1 "register_operand" "0") - (zero_extend:HI + (any_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))) (const_int 8)) (zero_extend:HI (truncate:QI - (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) + (div:HI (match_dup 1) (any_extend:HI (match_dup 2))))))) (clobber (reg:CC FLAGS_REG))] "TARGET_QIMODE_MATH" - "div{b}\t%2" + "div{b}\t%2" [(set_attr "type" "idiv") (set_attr "mode" "QI")])