[PATCH] nvptx: Add support for PTX highpart multiplications (HI/SI)
authorRoger Sayle <roger@nextmovesoftware.com>
Tue, 4 Aug 2020 13:31:42 +0000 (15:31 +0200)
committerTom de Vries <tdevries@suse.de>
Tue, 4 Aug 2020 22:44:10 +0000 (00:44 +0200)
This patch adds support for signed and unsigned, HImode and SImode highpart
multiplications to the nvptx backend.

This patch has been tested on nvptx-none hosted on x86_64-pc-linux-gnu
with a "make" and "make -k check" with no new failures with the
above patch.

2020-08-04  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog:

* config/nvptx/nvptx.md (smulhi3_highpart, smulsi3_highpart)
(umulhi3_highpart, umulsi3_highpart): New instructions.

gcc/testsuite/ChangeLog:

* gcc.target/nvptx/mul-hi.c: New test.
* gcc.target/nvptx/umul-hi.c: New test.

gcc/config/nvptx/nvptx.md
gcc/testsuite/gcc.target/nvptx/mul-hi.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/umul-hi.c [new file with mode: 0644]

index c23edcf34bf6148bcf22269885ea364153de96c1..4168190fa42d208f9930e1f3632e4f967c4d81d7 100644 (file)
   ""
   "%.\\tmul.wide.u32\\t%0, %1, %2;")
 
+(define_insn "smulhi3_highpart"
+  [(set (match_operand:HI 0 "nvptx_register_operand" "=R")
+       (truncate:HI
+        (lshiftrt:SI
+         (mult:SI (sign_extend:SI
+                   (match_operand:HI 1 "nvptx_register_operand" "R"))
+                  (sign_extend:SI
+                   (match_operand:HI 2 "nvptx_register_operand" "R")))
+         (const_int 16))))]
+  ""
+  "%.\\tmul.hi.s16\\t%0, %1, %2;")
+
+(define_insn "smulsi3_highpart"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (truncate:SI
+        (lshiftrt:DI
+         (mult:DI (sign_extend:DI
+                   (match_operand:SI 1 "nvptx_register_operand" "R"))
+                  (sign_extend:DI
+                   (match_operand:SI 2 "nvptx_register_operand" "R")))
+         (const_int 32))))]
+  ""
+  "%.\\tmul.hi.s32\\t%0, %1, %2;")
+
+(define_insn "umulhi3_highpart"
+  [(set (match_operand:HI 0 "nvptx_register_operand" "=R")
+       (truncate:HI
+        (lshiftrt:SI
+         (mult:SI (zero_extend:SI
+                   (match_operand:HI 1 "nvptx_register_operand" "R"))
+                  (zero_extend:SI
+                   (match_operand:HI 2 "nvptx_register_operand" "R")))
+         (const_int 16))))]
+  ""
+  "%.\\tmul.hi.u16\\t%0, %1, %2;")
+
+(define_insn "umulsi3_highpart"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (truncate:SI
+        (lshiftrt:DI
+         (mult:DI (zero_extend:DI
+                   (match_operand:SI 1 "nvptx_register_operand" "R"))
+                  (zero_extend:DI
+                   (match_operand:SI 2 "nvptx_register_operand" "R")))
+         (const_int 32))))]
+  ""
+  "%.\\tmul.hi.u32\\t%0, %1, %2;")
+
 ;; Shifts
 
 (define_insn "ashl<mode>3"
diff --git a/gcc/testsuite/gcc.target/nvptx/mul-hi.c b/gcc/testsuite/gcc.target/nvptx/mul-hi.c
new file mode 100644 (file)
index 0000000..c66fa38
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do assemble } */
+/* { dg-options "-O2 -save-temps" } */
+
+short smulhi3_highpart(short x, short y)
+{
+  return ((int)x * (int)y) >> 16;
+}
+
+int smulsi3_highpart(int x, int y)
+{
+  return ((long)x * (long)y) >> 32;
+}
+
+/* { dg-final { scan-assembler-times "mul.hi.s16" 1 } } */
+/* { dg-final { scan-assembler-times "mul.hi.s32" 1 } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/umul-hi.c b/gcc/testsuite/gcc.target/nvptx/umul-hi.c
new file mode 100644 (file)
index 0000000..3b35d6b
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do assemble } */
+/* { dg-options "-O2 -save-temps" } */
+
+unsigned short umulhi3_highpart(unsigned short x, unsigned short y)
+{
+  return ((unsigned int)x * (unsigned int)y) >> 16;
+}
+
+unsigned int umulsi3_highpart(unsigned int x, unsigned int y)
+{
+  return ((unsigned long)x * (unsigned long)y) >> 32;
+}
+
+/* { dg-final { scan-assembler-times "mul.hi.u16" 1 } } */
+/* { dg-final { scan-assembler-times "mul.hi.u32" 1 } } */