aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.ibm.com>2021-07-07 21:55:38 -0400
committerMichael Meissner <meissner@linux.ibm.com>2021-07-07 21:55:38 -0400
commit852b11da11a181df517c0348df044354ff0656d6 (patch)
tree3e9017445cdb5c294e189f9825ffd5c605fc0a51 /gcc
parentc24a97078221fad98d1f48ed9bd1af2094e1a01d (diff)
downloadgcc-852b11da11a181df517c0348df044354ff0656d6.zip
gcc-852b11da11a181df517c0348df044354ff0656d6.tar.gz
gcc-852b11da11a181df517c0348df044354ff0656d6.tar.bz2
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. 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/rs6000.md34
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c27
2 files changed, 61 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e84d031..2368153 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3234,6 +3234,14 @@
[(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 @@
(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 @@
(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 0000000..84685e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p10-vdivq-vmodq.c
@@ -0,0 +1,27 @@
+/* { dg-require-effective-target int128 } */
+/* { 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} } } */