i386.md (any_div): New code iterator.
authorUros Bizjak <uros@gcc.gnu.org>
Tue, 14 May 2019 16:18:06 +0000 (18:18 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 14 May 2019 16:18:06 +0000 (18:18 +0200)
* config/i386/i386.md (any_div): New code iterator.
(paired_mod): New code attribute.
(sgnprefix): Handle DIV and UDIV RTXes.
(u): Ditto.
(<u>divmod<mode>4): Macroize expander from divmod<mode>4
and udivmod<mode>4 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.
(*<u>divmod<mode>4_noext): Macroize insn from *divmod<mode>4_noext
and *udivmod<mode>4_noext patterns using any_div code iterator.
(*<u>divmod<mode>4_noext_zext_1): Macroize insn from
*divmod<mode>4_noext_zext_1 and *udivmod<mode>4_noext_zext_1
patterns using any_div code iterator.
(*<u>divmod<mode>4_noext_zext_2): Macroize insn from
*divmod<mode>4_noext_zext_2 and *udivmod<mode>4_noext_zext_2
patterns using any_div code iterator.
(<u>divmodhiqi3): Macroize insn from divmodhiqi3 and
udivmodhiqi3 patterns using any_extend code iterator.

From-SVN: r271179

gcc/ChangeLog
gcc/config/i386/i386.md

index 1af0304076aa410813a50da4036c5532c05d3a12..0e7bce8a46db046411edf4e47755ad1f297c9ca8 100644 (file)
@@ -1,12 +1,34 @@
+2019-05-14  Uroš Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (any_div): New code iterator.
+       (paired_mod): New code attribute.
+       (sgnprefix): Handle DIV and UDIV RTXes.
+       (u): Ditto.
+       (<u>divmod<mode>4): Macroize expander from divmod<mode>4
+       and udivmod<mode>4 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.
+       (*<u>divmod<mode>4_noext): Macroize insn from *divmod<mode>4_noext
+       and *udivmod<mode>4_noext patterns using any_div code iterator.
+       (*<u>divmod<mode>4_noext_zext_1): Macroize insn from
+       *divmod<mode>4_noext_zext_1 and *udivmod<mode>4_noext_zext_1
+       patterns using any_div code iterator.
+       (*<u>divmod<mode>4_noext_zext_2): Macroize insn from
+       *divmod<mode>4_noext_zext_2 and *udivmod<mode>4_noext_zext_2
+       patterns using any_div code iterator.
+       (<u>divmodhiqi3): Macroize insn from divmodhiqi3 and
+       udivmodhiqi3 patterns using any_extend code iterator.
+
 2019-05-14  Richard Biener  <rguenther@suse.de>
-       H.J. Lu  <hongjiu.lu@intel.com>
+           H.J. Lu  <hongjiu.lu@intel.com>
 
        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  <przemyslaw.wirkus@arm.com\>
+2019-05-14  Przemyslaw Wirkus  <przemyslaw.wirkus@arm.com>
 
        * internal-fn.def (SIGNBIT): New.
        * config/aarch64/aarch64-simd.md (signbitv2sf2): New expand
index edec0ab0386cca32e2be5037d0224253b37ff22f..05411221197fd25e86b6fc71f252a7d6211ad3c3 100644 (file)
 (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.
 \f
 ;; Divmod instructions.
 
-(define_expand "divmod<mode>4"
+(define_code_iterator any_div [div udiv])
+(define_code_attr paired_mod [(div "mod") (udiv "umod")])
+
+(define_expand "<u>divmod<mode>4"
   [(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)))
+                  (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
              (clobber (reg:CC FLAGS_REG))])])
 
 ;; Split with 8bit unsigned divide:
 ;;        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)))
+       (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_8BIT_IDIV
    && TARGET_QIMODE_MATH
 (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)))
+       (<paired_mod>: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 ()"
 (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"))))
+         (<paired_mod>: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 ()"
   [(set_attr "type" "multi")
    (set_attr "mode" "<MODE>")])
 
+(define_insn_and_split "udivmod<mode>4_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" "<MODE>")])
+
 (define_insn_and_split "divmodsi4_zext_1"
   [(set (match_operand:DI 0 "register_operand" "=a")
        (zero_extend:DI
    (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))])
   [(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
    (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))])
   [(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 "*divmod<mode>4"
   [(set (match_operand:SWIM248 0 "register_operand" "=a")
        (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
   [(set_attr "type" "multi")
    (set_attr "mode" "<MODE>")])
 
+(define_insn_and_split "*udivmod<mode>4"
+  [(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" "<MODE>")])
+
+;; Optimize division or modulo by constant power of 2, if the constant
+;; materializes only after expansion.
+(define_insn_and_split "*udivmod<mode>4_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:<MODE> (match_dup 2) (match_dup 4)))
+             (clobber (reg:CC FLAGS_REG))])
+   (parallel [(set (match_dup 1) (and:<MODE> (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" "<MODE>")])
+
 (define_insn_and_split "*divmodsi4_zext_1"
   [(set (match_operand:DI 0 "register_operand" "=a")
        (zero_extend:DI
    (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))])
   [(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
    (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))])
   [(set_attr "type" "multi")
    (set_attr "mode" "SI")])
 
-(define_insn "*divmod<mode>4_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 "*<u>divmod<mode>4_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)))
+       (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
    (use (match_operand:SWIM248 4 "register_operand" "1"))
    (clobber (reg:CC FLAGS_REG))]
   ""
-  "idiv{<imodesuffix>}\t%3"
+  "<sgnprefix>div{<imodesuffix>}\t%3"
   [(set_attr "type" "idiv")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*divmodsi4_noext_zext_1"
+(define_insn "*<u>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)))
+       (<paired_mod>: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"
+  "<sgnprefix>div{l}\t%3"
   [(set_attr "type" "idiv")
    (set_attr "mode" "SI")])
 
-(define_insn "*divmodsi4_noext_zext_2"
+(define_insn "*<u>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"))))
+         (<paired_mod>: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"
+  "<sgnprefix>div{l}\t%3"
   [(set_attr "type" "idiv")
    (set_attr "mode" "SI")])
 
 {
   rtx div, mod;
   rtx tmp0, tmp1;
-  
+
   tmp0 = gen_reg_rtx (HImode);
   tmp1 = gen_reg_rtx (HImode);
 
   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 "udivmod<mode>4"
-  [(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>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 "udivmod<mode>4_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" "<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 "*udivmod<mode>4"
-  [(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" "<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 "*udivmod<mode>4_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:<MODE> (match_dup 2) (match_dup 4)))
-             (clobber (reg:CC FLAGS_REG))])
-   (parallel [(set (match_dup 1) (and:<MODE> (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" "<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 "*udivmod<mode>4_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{<imodesuffix>}\t%3"
-  [(set_attr "type" "idiv")
-   (set_attr "mode" "<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
 {
   rtx div, mod;
   rtx tmp0, tmp1;
-  
+
   tmp0 = gen_reg_rtx (HImode);
   tmp1 = gen_reg_rtx (HImode);
 
   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 "<u>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"
+  "<sgnprefix>div{b}\t%2"
   [(set_attr "type" "idiv")
    (set_attr "mode" "QI")])