diff mbox series

Repost: [PATCH] Generate 128-bit int divide/modulus on power10.

Message ID 20210707195544.GA26378@ibm-toto.the-meissners.org
State New
Headers show
Series Repost: [PATCH] Generate 128-bit int divide/modulus on power10. | expand

Commit Message

Michael Meissner July 7, 2021, 7:55 p.m. UTC
[PATCH] Generate 128-bit int divide/modulus on power10.

This patch adds support for the VDIVSQ, VDIVUQ, VMODSQ, and VMODUQ
instructions to do 128-bit arithmetic.

Ideally this patch can be approved in time to be back ported to GCC 11.2.

Can I check this into the master branch, and eventually into GCC 11?

2021-07-07  Michael Meissner  <meissner@linux.ibm.com>

gcc/
	PR target/100809
	* config/rs6000/rs6000.md (udivti3): New insn.
	(divti3): New insn.
	(umodti3): New insn.
	(modti3): New insn.

gcc/testsuite/
	PR target/100809
	* gcc.target/powerpc/p10-vdivq-vmodq.c: New test.
---
 gcc/config/rs6000/rs6000.md                   | 34 +++++++++++++++++++
 .../gcc.target/powerpc/p10-vdivq-vmodq.c      | 27 +++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c

Comments

Segher Boessenkool July 7, 2021, 11:23 p.m. UTC | #1
On Wed, Jul 07, 2021 at 03:55:44PM -0400, Michael Meissner wrote:
> This patch adds support for the VDIVSQ, VDIVUQ, VMODSQ, and VMODUQ
> instructions to do 128-bit arithmetic.

> gcc/
> 	PR target/100809
> 	* config/rs6000/rs6000.md (udivti3): New insn.
> 	(divti3): New insn.
> 	(umodti3): New insn.
> 	(modti3): New insn.
> 
> gcc/testsuite/
> 	PR target/100809
> 	* gcc.target/powerpc/p10-vdivq-vmodq.c: New test.

>  2 files changed, 61 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
> 
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index e84d0311cc2..4e53cf28dde 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -3234,6 +3234,14 @@ (define_insn "udiv<mode>3"
>    [(set_attr "type" "div")
>     (set_attr "size" "<bits>")])
>  
> +(define_insn "udivti3"
> +  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
> +        (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")

(every eight leading spaces should be tabs -- multiple times here)

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
> @@ -0,0 +1,27 @@
> +/* { dg-require-effective-target lp64 } */

int128, instead.  There is nothing here that needs lp64.  If there was,
that should be commented here, too.

Okay for trunk with those fixes.  Also okay for all backports.  Please
make sure it tested on all usual platforms before backporting.  Thanks!


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e84d0311cc2..4e53cf28dde 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3234,6 +3234,14 @@  (define_insn "udiv<mode>3"
   [(set_attr "type" "div")
    (set_attr "size" "<bits>")])
 
+(define_insn "udivti3"
+  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+        (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")
+		 (match_operand:TI 2 "altivec_register_operand" "v")))]
+  "TARGET_POWER10 && TARGET_POWERPC64"
+  "vdivuq %0,%1,%2"
+  [(set_attr "type" "vecdiv")
+   (set_attr "size" "128")])
 
 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
 ;; modulus.  If it isn't a power of two, force operands into register and do
@@ -3324,6 +3332,15 @@  (define_insn_and_split "*div<mode>3_sra_dot2"
    (set_attr "length" "8,12")
    (set_attr "cell_micro" "not")])
 
+(define_insn "divti3"
+  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+        (div:TI (match_operand:TI 1 "altivec_register_operand" "v")
+		(match_operand:TI 2 "altivec_register_operand" "v")))]
+  "TARGET_POWER10 && TARGET_POWERPC64"
+  "vdivsq %0,%1,%2"
+  [(set_attr "type" "vecdiv")
+   (set_attr "size" "128")])
+
 (define_expand "mod<mode>3"
   [(set (match_operand:GPR 0 "gpc_reg_operand")
 	(mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
@@ -3424,6 +3441,23 @@  (define_peephole2
 	(minus:GPR (match_dup 1)
 		   (match_dup 3)))])
 
+(define_insn "umodti3"
+  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+        (umod:TI (match_operand:TI 1 "altivec_register_operand" "v")
+		 (match_operand:TI 2 "altivec_register_operand" "v")))]
+  "TARGET_POWER10 && TARGET_POWERPC64"
+  "vmoduq %0,%1,%2"
+  [(set_attr "type" "vecdiv")
+   (set_attr "size" "128")])
+
+(define_insn "modti3"
+  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+        (mod:TI (match_operand:TI 1 "altivec_register_operand" "v")
+		(match_operand:TI 2 "altivec_register_operand" "v")))]
+  "TARGET_POWER10 && TARGET_POWERPC64"
+  "vmodsq %0,%1,%2"
+  [(set_attr "type" "vecdiv")
+   (set_attr "size" "128")])
 
 ;; Logical instructions
 ;; The logical instructions are mostly combined by using match_operator,
diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
new file mode 100644
index 00000000000..cd29b0a4b6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
@@ -0,0 +1,27 @@ 
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+unsigned __int128 u_div(unsigned __int128 a, unsigned __int128 b)
+{
+   return a/b;
+}
+
+unsigned __int128 u_mod(unsigned __int128 a, unsigned __int128 b)
+{
+   return a%b;
+}
+__int128 s_div(__int128 a, __int128 b)
+{
+   return a/b;
+}
+
+__int128 s_mod(__int128 a, __int128 b)
+{
+   return a%b;
+}
+
+/* { dg-final { scan-assembler {\mvdivsq\M} } } */
+/* { dg-final { scan-assembler {\mvdivuq\M} } } */
+/* { dg-final { scan-assembler {\mvmodsq\M} } } */
+/* { dg-final { scan-assembler {\mvmoduq\M} } } */