From 37a4c06f3dac9b0b831a8f34af73422aa4f42fbe Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Tue, 4 Aug 2020 15:31:42 +0200 Subject: [PATCH] [PATCH] nvptx: Add support for PTX highpart multiplications (HI/SI) 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 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 | 48 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/nvptx/mul-hi.c | 15 ++++++++ gcc/testsuite/gcc.target/nvptx/umul-hi.c | 15 ++++++++ 3 files changed, 78 insertions(+) create mode 100644 gcc/testsuite/gcc.target/nvptx/mul-hi.c create mode 100644 gcc/testsuite/gcc.target/nvptx/umul-hi.c diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md index c23edcf34bf..4168190fa42 100644 --- a/gcc/config/nvptx/nvptx.md +++ b/gcc/config/nvptx/nvptx.md @@ -568,6 +568,54 @@ "" "%.\\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 "ashl3" diff --git a/gcc/testsuite/gcc.target/nvptx/mul-hi.c b/gcc/testsuite/gcc.target/nvptx/mul-hi.c new file mode 100644 index 00000000000..c66fa38623b --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/mul-hi.c @@ -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 index 00000000000..3b35d6b50ec --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/umul-hi.c @@ -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 } } */ -- 2.30.2