public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, i386]: Macroize DIVMOD patterns
@ 2019-05-14 16:22 Uros Bizjak
  2019-05-15 12:16 ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Uros Bizjak @ 2019-05-14 16:22 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1427 bytes --]

Recent work by Richard Sandiford [1] enabled the possibility to
macroize DIVMOD patterns in i386.md.

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.

The patch also reorders DIVMOD patterns a bit.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

[1] https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00560.html

Uros.

[-- Attachment #2: p.diff.txt --]
[-- Type: text/plain, Size: 29160 bytes --]

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index edec0ab0386c..05411221197f 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 @@
 \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:
@@ -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)))
+	(<paired_mod>: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)))
+	(<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 ()"
@@ -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"))))
+	  (<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 ()"
@@ -7568,6 +7574,28 @@
   [(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
@@ -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 "*divmod<mode>4"
   [(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" "<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
@@ -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 "*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")])
 
@@ -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 "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
@@ -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 "<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")])
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-05-15 18:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-14 16:22 [PATCH, i386]: Macroize DIVMOD patterns Uros Bizjak
2019-05-15 12:16 ` Richard Biener
2019-05-15 12:20   ` Jakub Jelinek
2019-05-15 12:29   ` Uros Bizjak
2019-05-15 18:04     ` Uros Bizjak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).