This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, MIPS] Add dmul Octeon instruction


First of all I am sorry because I apparently missed the discussion on
the list when the 64-bit three-op multiplication was removed.  We have
this instruction so I need to put it back.

Now the SI and DI expanders are identical so I replaced them with a
mode-iterator template.  This required the new <D> mode-iterator attribute.

I didn't convert the actual patterns because the TARGET_FIX_R4000 part
is only used in the SI pattern.  I could of course turn this into a
template with an && <MODE>mode == SImode added to the TARGET_FIX_R4000
check but I wasn't sure.

I renamed the 3-op pattern to have the _mul3 suffix rather than _mult3.
 The suffix usually holds the mnemonic for the instruction which is
usually <d>mul in this case.

Besides new Octeon dmul tests I also added a dmult test to make sure I
didn't break that.  This should also work with mips16.

Bootstrapped and tested on top the other already-submitted patches on
mips64octeon-unknown-linux-gnu.

OK to install?

Adam


	* config/mips/mips.h (ISA_HAS_DMUL3): New macro.
	* config/mips/mips.md (D): New mode attribute.
	(mulsi3, muldi3): Merge it into ...
	(mul<mode>3): ... new template.  Use _mul3 ending for 3-op
	patterns.
	(muldi3_mul3): New pattern.
	(mulsi3_mult3): Rename to mulsi3_mul3.

testsuite/
	* gcc.target/mips/octeon-dmul-1.c: New test.
	* gcc.target/mips/octeon-dmul-2.c: New test.
	* gcc.target/mips/dmult-1.c: New test.

Index: gcc/config/mips/mips.h
===================================================================
*** gcc.orig/config/mips/mips.h	2008-08-27 11:01:16.000000000 -0700
--- gcc/config/mips/mips.h	2008-08-27 11:01:17.000000000 -0700
*************** enum mips_code_readable_setting {
*** 778,783 ****
--- 778,786 ----
  				  || ISA_MIPS64R2)			\
  				 && !TARGET_MIPS16)
  
+ /* ISA has a three-operand multiplication instruction.  */
+ #define ISA_HAS_DMUL3		(TARGET_64BIT && TARGET_OCTEON)
+ 
  /* ISA has the floating-point conditional move instructions introduced
     in mips4.  */
  #define ISA_HAS_FP_CONDMOVE	((ISA_MIPS4				\
Index: gcc/config/mips/mips.md
===================================================================
*** gcc.orig/config/mips/mips.md	2008-08-27 11:01:16.000000000 -0700
--- gcc/config/mips/mips.md	2008-08-27 11:01:17.000000000 -0700
***************
*** 689,694 ****
--- 689,701 ----
  		     (HA "") (SA "") (DA "d")
  		     (UHA "") (USA "") (UDA "d")])
  
+ ;; Same as d but upper-case.
+ (define_mode_attr D [(SI "") (DI "D")
+ 		     (QQ "") (HQ "") (SQ "") (DQ "D")
+ 		     (UQQ "") (UHQ "") (USQ "") (UDQ "D")
+ 		     (HA "") (SA "") (DA "D")
+ 		     (UHA "") (USA "") (UDA "D")])
+ 
  ;; This attribute gives the length suffix for a sign- or zero-extension
  ;; instruction.
  (define_mode_attr size [(QI "b") (HI "h")])
***************
*** 1326,1360 ****
  ;; These processors have PRId values of 0x00004220 and 0x00004300,
  ;; respectively.
  
! (define_expand "mulsi3"
!   [(set (match_operand:SI 0 "register_operand")
! 	(mult:SI (match_operand:SI 1 "register_operand")
! 		 (match_operand:SI 2 "register_operand")))]
    ""
  {
!   if (ISA_HAS_MUL3)
!     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
    else if (TARGET_FIX_R4000)
!     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
!   else
!     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
!   DONE;
! })
! 
! (define_expand "muldi3"
!   [(set (match_operand:DI 0 "register_operand")
! 	(mult:DI (match_operand:DI 1 "register_operand")
! 		 (match_operand:DI 2 "register_operand")))]
!   "TARGET_64BIT"
! {
!   if (TARGET_FIX_R4000)
!     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
    else
!     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
    DONE;
  })
  
! (define_insn "mulsi3_mult3"
    [(set (match_operand:SI 0 "register_operand" "=d,l")
  	(mult:SI (match_operand:SI 1 "register_operand" "d,d")
  		 (match_operand:SI 2 "register_operand" "d,d")))
--- 1333,1355 ----
  ;; These processors have PRId values of 0x00004220 and 0x00004300,
  ;; respectively.
  
! (define_expand "mul<mode>3"
!   [(set (match_operand:GPR 0 "register_operand")
! 	(mult:GPR (match_operand:GPR 1 "register_operand")
! 		  (match_operand:GPR 2 "register_operand")))]
    ""
  {
!   if (ISA_HAS_<D>MUL3)
!     emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2]));
    else if (TARGET_FIX_R4000)
!     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
    else
!     emit_insn
!       (gen_mul<mode>3_internal (operands[0], operands[1], operands[2]));
    DONE;
  })
  
! (define_insn "mulsi3_mul3"
    [(set (match_operand:SI 0 "register_operand" "=d,l")
  	(mult:SI (match_operand:SI 1 "register_operand" "d,d")
  		 (match_operand:SI 2 "register_operand" "d,d")))
***************
*** 1370,1375 ****
--- 1365,1384 ----
    [(set_attr "type" "imul3,imul")
     (set_attr "mode" "SI")])
  
+ (define_insn "muldi3_mul3"
+   [(set (match_operand:DI 0 "register_operand" "=d,l")
+ 	(mult:DI (match_operand:DI 1 "register_operand" "d,d")
+ 		 (match_operand:DI 2 "register_operand" "d,d")))
+    (clobber (match_scratch:DI 3 "=l,X"))]
+   "ISA_HAS_DMUL3"
+ {
+   if (which_alternative == 1)
+     return "dmult\t%1,%2";
+   return "dmul\t%0,%1,%2";
+ }
+   [(set_attr "type" "imul3,imul")
+    (set_attr "mode" "DI")])
+ 
  ;; If a register gets allocated to LO, and we spill to memory, the reload
  ;; will include a move from LO to a GPR.  Merge it into the multiplication
  ;; if it can set the GPR directly.
Index: gcc/testsuite/gcc.target/mips/dmult-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/dmult-1.c	2008-08-27 11:37:28.000000000 -0700
***************
*** 0 ****
--- 1,12 ----
+ /* { dg-do compile { target mips16_attribute } } */
+ /* { dg-mips-options "-mips64 -mgp64" } */
+ /* { dg-add-options mips16_attribute } */
+ /* { dg-final { scan-assembler "\tdmult\t" } } */
+ /* { dg-final { scan-assembler "\tmflo\t" } } */
+ /* { dg-final { scan-assembler-not "\tdmul\t" } } */
+ 
+ long long
+ f (long long a, long long b)
+ {
+   return a * b;
+ }
Index: gcc/testsuite/gcc.target/mips/octeon-dmul-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/octeon-dmul-1.c	2008-08-27 11:20:30.000000000 -0700
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-march=octeon -mgp64" } */
+ /* { dg-final { scan-assembler "\tdmul\t" } } */
+ /* { dg-final { scan-assembler-not "\tdmult\t" } } */
+ /* { dg-final { scan-assembler-not "\tmflo\t" } } */
+ 
+ NOMIPS16 long long
+ f (long long a, long long b)
+ {
+   return a * b;
+ }
Index: gcc/testsuite/gcc.target/mips/octeon-dmul-2.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/octeon-dmul-2.c	2008-08-27 11:20:38.000000000 -0700
***************
*** 0 ****
--- 1,9 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-march=octeon -mgp64" } */
+ /* { dg-final { scan-assembler-not "\tdmul" } } */
+ 
+ NOMIPS16 long long
+ f (long long a)
+ {
+   return a * 7;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]