This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [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: Sun, 11 Oct 2009 00:18:25 -0700
- Subject: Re: [PATCH, MIPS] Use dmult in 64-bit signed widening multiplication
- References: <19152.61180.167694.684699@ropi.home>
Adam Nemet <anemet@caviumnetworks.com> writes:
> 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")
^^
This should be =l. I am retesting with that.
Adam
> ! (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;
> + }