This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, MIPS] Use dmult in 64-bit signed widening multiplication
- From: Adam Nemet <anemet at caviumnetworks dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 10 Oct 2009 13:30:52 -0700
- Subject: [PATCH, MIPS] Use dmult in 64-bit signed widening multiplication
While working on one of the and-ext rtx-cost followups, I've noticed that we
were using mult and then bit-combining lo and hi rather than using dmult with
the already sign-extended operands.
The related pattern mulsidi3_64bit_hilo is still needed for the mul-highpart
pattern. It's better to have mult,mfhi than dmult,mflo,sra.
There should also be a dmul variant of mulsidi3 but that's something for
another patch.
Bootstrapped and regtested on mips64octeon-linux-gnu. Regtested
mipsisa64r2-elf.
OK for mainline or should I queue this for stage 1?
Adam
* config/mips/mips.md (mulsidi3_64bit): New pattern.
(<u>mulsidi3_64bit): Unmacroize by removing the signed version and
rename into ...
(umulsidi3_64bit): ... this.
testsuite/
* gcc.target/mips/dmult-2.c: New test.
Index: gcc/config/mips/mips.md
===================================================================
*** gcc.orig/config/mips/mips.md 2009-10-09 18:48:39.000000000 -0700
--- gcc/config/mips/mips.md 2009-10-10 13:26:06.000000000 -0700
*************** (define_insn "<u>mulsidi3_32bit_r4000"
*** 1879,1896 ****
(set_attr "mode" "SI")
(set_attr "length" "12")])
! (define_insn_and_split "<u>mulsidi3_64bit"
[(set (match_operand:DI 0 "register_operand" "=d")
! (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
! (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
(clobber (match_scratch:TI 3 "=x"))
(clobber (match_scratch:DI 4 "=d"))]
"TARGET_64BIT && !TARGET_FIX_R4000"
"#"
"&& reload_completed"
[(set (match_dup 3)
! (unspec:TI [(mult:DI (any_extend:DI (match_dup 1))
! (any_extend:DI (match_dup 2)))]
UNSPEC_SET_HILO))
;; OP4 <- LO, OP0 <- HI
--- 1879,1908 ----
(set_attr "mode" "SI")
(set_attr "length" "12")])
! ;; SI mode values are always sign-extended into 64-bit values so they can be
! ;; used directly in 64-bit multiplication.
! (define_insn "mulsidi3_64bit"
! [(set (match_operand:DI 0 "register_operand" "=x")
! (mult:DI
! (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
! (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
! "TARGET_64BIT && !TARGET_FIX_R4000"
! "dmult\t%1,%2"
! [(set_attr "type" "imul")
! (set_attr "mode" "DI")])
!
! (define_insn_and_split "umulsidi3_64bit"
[(set (match_operand:DI 0 "register_operand" "=d")
! (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
! (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
(clobber (match_scratch:TI 3 "=x"))
(clobber (match_scratch:DI 4 "=d"))]
"TARGET_64BIT && !TARGET_FIX_R4000"
"#"
"&& reload_completed"
[(set (match_dup 3)
! (unspec:TI [(mult:DI (zero_extend:DI (match_dup 1))
! (zero_extend:DI (match_dup 2)))]
UNSPEC_SET_HILO))
;; OP4 <- LO, OP0 <- HI
Index: gcc/testsuite/gcc.target/mips/dmult-2.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/dmult-2.c 2009-10-10 13:01:54.000000000 -0700
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-options "-O -mgp64" } */
+ /* { dg-final { scan-assembler "\tdmult\t" } } */
+ /* { dg-final { scan-assembler-not "\tmult\t" } } */
+ /* { dg-final { scan-assembler-not "\tmfhi\t" } } */
+
+ long long
+ f (int i, int j)
+ {
+ i++;
+ return (long long) i * j;
+ }