* config/mips/predicates.md (hilo_operand): New predicate.
authornemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Oct 2009 07:03:53 +0000 (07:03 +0000)
committernemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Oct 2009 07:03:53 +0000 (07:03 +0000)
* config/mips/mips.md (<u>mulsidi3_64bit): Change it to a
define_insn.  Correct !ISA_HAS_EXT_INS length from 24 to 28.  Move
splitter part from here ...:
(<u>mulsidi3_64bit splitter for !ISA_HAS_EXT_INS): ... to here.  Swap
op0 and op4 to match the DINS case.
(<u>mulsidi3_64bit splitter for ISA_HAS_EXT_INS): New splitter.

testsuite/
* gcc.target/mips/mult-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153538 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mips/mips.md
gcc/config/mips/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/mult-1.c [new file with mode: 0644]

index b46a2ef..bda1da3 100644 (file)
@@ -1,4 +1,14 @@
-       2009-09-27  Andy Hutchinson  <hutchinsonandy@gcc.gnu.org>
+2009-10-24  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * config/mips/predicates.md (hilo_operand): New predicate.
+       * config/mips/mips.md (<u>mulsidi3_64bit): Change it to a
+       define_insn.  Correct !ISA_HAS_EXT_INS length from 24 to 28.  Move
+       splitter part from here ...:
+       (<u>mulsidi3_64bit splitter for !ISA_HAS_EXT_INS): ... to here.  Swap
+       op0 and op4 to match the DINS case.
+       (<u>mulsidi3_64bit splitter for ISA_HAS_EXT_INS): New splitter.
+
+2009-10-24  Andy Hutchinson  <hutchinsonandy@gcc.gnu.org>
 
        PR middle-end/19154
        * avr.md (QIDI): Add new mode iterator.
index 2d11ed0..5005bf7 100644 (file)
    (set_attr "mode" "SI")
    (set_attr "length" "12")])
 
-(define_insn_and_split "<u>mulsidi3_64bit"
+(define_insn "<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:DI 4 "=d"))]
   "TARGET_64BIT && !TARGET_FIX_R4000"
   "#"
-  "&& reload_completed"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")
+   (set (attr "length")
+       (if_then_else (ne (symbol_ref "ISA_HAS_EXT_INS") (const_int 0))
+                     (const_int 16)
+                     (const_int 28)))])
+
+(define_split
+  [(set (match_operand:DI 0 "d_operand")
+       (mult:DI (any_extend:DI (match_operand:SI 1 "d_operand"))
+                (any_extend:DI (match_operand:SI 2 "d_operand"))))
+   (clobber (match_operand:TI 3 "hilo_operand"))
+   (clobber (match_operand:DI 4 "d_operand"))]
+  "TARGET_64BIT && !TARGET_FIX_R4000 && ISA_HAS_EXT_INS && 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))
+
+   ;; OP0 <- LO, OP4 <- HI
+   (set (match_dup 0) (match_dup 5))
+   (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_MFHI))
+
+   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 32))
+       (match_dup 4))]
+  { operands[5] = gen_rtx_REG (DImode, LO_REGNUM); })
+
+(define_split
+  [(set (match_operand:DI 0 "d_operand")
+       (mult:DI (any_extend:DI (match_operand:SI 1 "d_operand"))
+                (any_extend:DI (match_operand:SI 2 "d_operand"))))
+   (clobber (match_operand:TI 3 "hilo_operand"))
+   (clobber (match_operand:DI 4 "d_operand"))]
+  "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_EXT_INS && 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
-   (set (match_dup 4) (match_dup 5))
-   (set (match_dup 0) (unspec:DI [(match_dup 3)] UNSPEC_MFHI))
+   ;; OP0 <- LO, OP4 <- HI
+   (set (match_dup 0) (match_dup 5))
+   (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_MFHI))
 
    ;; Zero-extend OP4.
-   (set (match_dup 4)
-       (ashift:DI (match_dup 4)
+   (set (match_dup 0)
+       (ashift:DI (match_dup 0)
                   (const_int 32)))
-   (set (match_dup 4)
-       (lshiftrt:DI (match_dup 4)
+   (set (match_dup 0)
+       (lshiftrt:DI (match_dup 0)
                     (const_int 32)))
 
    ;; Shift OP0 into place.
-   (set (match_dup 0)
-       (ashift:DI (match_dup 0)
+   (set (match_dup 4)
+       (ashift:DI (match_dup 4)
                   (const_int 32)))
 
    ;; OR the two halves together
    (set (match_dup 0)
        (ior:DI (match_dup 0)
                (match_dup 4)))]
-  { operands[5] = gen_rtx_REG (DImode, LO_REGNUM); }
-  [(set_attr "type" "imul")
-   (set_attr "mode" "SI")
-   (set_attr "length" "24")])
+  { operands[5] = gen_rtx_REG (DImode, LO_REGNUM); })
 
 (define_insn "<u>mulsidi3_64bit_hilo"
   [(set (match_operand:TI 0 "register_operand" "=x")
index e1cb457..7430dd3 100644 (file)
   (and (match_code "reg")
        (match_test "REGNO (op) == LO_REGNUM")))
 
+(define_predicate "hilo_operand"
+  (and (match_code "reg")
+       (match_test "MD_REG_P (REGNO (op))")))
+
 (define_predicate "fcc_reload_operand"
   (and (match_code "reg,subreg")
        (match_test "ST_REG_P (true_regnum (op))")))
index 99c187e..e497e3d 100644 (file)
@@ -1,3 +1,7 @@
+2009-10-24  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * gcc.target/mips/mult-1.c: New test.
+
 2009-10-24  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/41784
diff --git a/gcc/testsuite/gcc.target/mips/mult-1.c b/gcc/testsuite/gcc.target/mips/mult-1.c
new file mode 100644 (file)
index 0000000..d82a477
--- /dev/null
@@ -0,0 +1,14 @@
+/* For SI->DI widening multiplication we should use DINS to combine the two
+   halves.  */
+/* { dg-options "-O -mgp64 isa_rev>=2" } */
+/* { dg-final { scan-assembler "\tdins\t" } } */
+/* { dg-final { scan-assembler-not "\tdsll\t" } } */
+/* { dg-final { scan-assembler-not "\tdsrl\t" } } */
+/* { dg-final { scan-assembler-not "\tor\t" } } */
+
+NOMIPS16 unsigned long long
+f (unsigned int i, unsigned int j)
+{
+  i++;
+  return (unsigned long long) i * j;
+}