public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] Patch to smsub_widen_optab & umsub_widen_optab
@ 2007-05-08  0:16 Fu, Chao-Ying
  2007-05-08  8:23 ` Richard Sandiford
  0 siblings, 1 reply; 4+ messages in thread
From: Fu, Chao-Ying @ 2007-05-08  0:16 UTC (permalink / raw)
  To: gcc-patches, Richard Sandiford; +Cc: Stephens, Nigel, Thekkath, Radhika

[-- Attachment #1: Type: text/plain, Size: 1662 bytes --]

Hi,

  This patch extends the MADD patch posted by Richard on
http://gcc.gnu.org/ml/gcc-patches/2007-04/msg01559.html
to support MSUB.  Eight MIPS tests are included.
The patch and tests are very similar to the original patch,
except that the reversed-operand test is not included.
If I swap the subtrahend and the minuend in the test,
GCC does not swap operands back (before expanding tree to rtl)
and fails to recognize the MSUB pattern.
Ok to commit?  Thanks!

Regards,
Chao-ying

gcc/
2007-05-07  Chao-ying Fu  <fu@mips.com>

	* doc/md.texi (msub@var{m}@var{n}4, usub@var{m}@var{n}4): Document.
	* optabs.h (OTI_smsub_widen, OTI_umsub_widen): New optab_indexes.
	(smsub_widen_optab, umsub_widen_optab): Define.
	* optabs.c (init_optabs): Initialize smsub_widen_optab and
	umsub_widen_optab.
	* genopinit.c (optabs): Fill in smsub_widen_optab and
	umsub_widen_optab.
	* expr.c (expand_expr_real_1): Try to use smsub_widen_optab
	and umsub_widen_optab to implement multiply-subtract sequences.
	* config/mips/mips.md (*msac<u>_di): Rename to...
	(<u>msubsidi4): ...this.  Extend condition to include
	GENERATE_MADD_MSUB and TARGET_DSPR2.  Change the constraint
	of operand 0 to "ka" and use the three-operand form of msub<u>
	for TARGET_DSPR2.
	* config/mips/mips-dspr2.md (mips_msub, mips_msubu): Convert
	to define_expands.

gcc/testsuite/
2007-05-07  Chao-ying Fu  <fu@mips.com>

	* gcc.target/mips/msub-1.c, gcc.target/mips/msub-2.c,
	* gcc.target/mips/msub-3.c, gcc.target/mips/msub-4.c,
	* gcc.target/mips/msubu-1.c, gcc.target/mips/msubu-2.c,
	* gcc.target/mips/msubu-3.c, gcc.target/mips/msubu-4.c: New tests.

[-- Attachment #2: gcc.diff --]
[-- Type: application/octet-stream, Size: 8116 bytes --]

Index: doc/md.texi
===================================================================
--- doc/md.texi	(revision 124503)
+++ doc/md.texi	(working copy)
@@ -3687,6 +3687,25 @@
 Like @code{madd@var{m}@var{n}4}, but zero-extend the multiplication
 operands instead of sign-extending them.
 
+@cindex @code{msub@var{m}@var{n}4} instruction pattern
+@item @samp{msub@var{m}@var{n}4}
+Multiply operands 1 and 2, sign-extend them to mode @var{n}, subtract the
+result from operand 3, and store the result in operand 0.  Operands 1 and 2
+have mode @var{m} and operands 0 and 3 have mode @var{n}.
+Both modes must be integer modes and @var{n} must be twice
+the size of @var{m}.
+
+In other words, @code{msub@var{m}@var{n}4} is like
+@code{mul@var{m}@var{n}3} except that it also subtracts the result
+from operand 3.
+
+These instructions are not allowed to @code{FAIL}.
+
+@cindex @code{umsub@var{m}@var{n}4} instruction pattern
+@item @samp{umsub@var{m}@var{n}4}
+Like @code{msub@var{m}@var{n}4}, but zero-extend the multiplication
+operands instead of sign-extending them.
+
 @cindex @code{divmod@var{m}4} instruction pattern
 @item @samp{divmod@var{m}4}
 Signed division that produces both a quotient and a remainder.
Index: optabs.c
===================================================================
--- optabs.c	(revision 124503)
+++ optabs.c	(working copy)
@@ -5442,6 +5442,8 @@
   usmul_widen_optab = init_optab (UNKNOWN);
   smadd_widen_optab = init_optab (UNKNOWN);
   umadd_widen_optab = init_optab (UNKNOWN);
+  smsub_widen_optab = init_optab (UNKNOWN);
+  umsub_widen_optab = init_optab (UNKNOWN);
   sdiv_optab = init_optab (DIV);
   sdivv_optab = init_optabv (DIV);
   sdivmod_optab = init_optab (UNKNOWN);
Index: optabs.h
===================================================================
--- optabs.h	(revision 124503)
+++ optabs.h	(working copy)
@@ -92,6 +92,12 @@
   /* Unigned multiply and add with the result and addend one machine mode
      wider than the multiplicand and multiplier.  */
   OTI_umadd_widen,
+  /* Signed multiply and subtract the result and minuend one machine mode
+     wider than the multiplicand and multiplier.  */
+  OTI_smsub_widen,
+  /* Unigned multiply and subtract the result and minuend one machine mode
+     wider than the multiplicand and multiplier.  */
+  OTI_umsub_widen,
 
   /* Signed divide */
   OTI_sdiv,
@@ -317,6 +323,8 @@
 #define usmul_widen_optab (optab_table[OTI_usmul_widen])
 #define smadd_widen_optab (optab_table[OTI_smadd_widen])
 #define umadd_widen_optab (optab_table[OTI_umadd_widen])
+#define smsub_widen_optab (optab_table[OTI_smsub_widen])
+#define umsub_widen_optab (optab_table[OTI_umsub_widen])
 #define sdiv_optab (optab_table[OTI_sdiv])
 #define smulv_optab (optab_table[OTI_smulv])
 #define sdivv_optab (optab_table[OTI_sdivv])
Index: genopinit.c
===================================================================
--- genopinit.c	(revision 124503)
+++ genopinit.c	(working copy)
@@ -87,6 +87,8 @@
   "usmul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(usmul$a$b3$)$N",
   "smadd_widen_optab->handlers[$B].insn_code = CODE_FOR_$(madd$a$b4$)$N",
   "umadd_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umadd$a$b4$)$N",
+  "smsub_widen_optab->handlers[$B].insn_code = CODE_FOR_$(msub$a$b4$)$N",
+  "umsub_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umsub$a$b4$)$N",
   "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
   "sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
   "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
Index: expr.c
===================================================================
--- expr.c	(revision 124503)
+++ expr.c	(working copy)
@@ -8133,6 +8133,47 @@
       return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
 
     case MINUS_EXPR:
+      /* Check if this is a case for multiplication and subtraction.  */
+      if (TREE_CODE (type) == INTEGER_TYPE
+	  && TREE_CODE (TREE_OPERAND (exp, 1)) == MULT_EXPR)
+	{
+	  tree subsubexp0, subsubexp1;
+	  enum tree_code code0, code1;
+
+	  subexp1 = TREE_OPERAND (exp, 1);
+	  subsubexp0 = TREE_OPERAND (subexp1, 0);
+	  subsubexp1 = TREE_OPERAND (subexp1, 1);
+	  code0 = TREE_CODE (subsubexp0);
+	  code1 = TREE_CODE (subsubexp1);
+	  if (code0 == NOP_EXPR && code1 == NOP_EXPR
+	      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
+		  < TYPE_PRECISION (TREE_TYPE (subsubexp0)))
+	      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
+		  == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))
+	      && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
+		  == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))))
+	    {
+	      tree op0type = TREE_TYPE (TREE_OPERAND (subsubexp0, 0));
+	      enum machine_mode innermode = TYPE_MODE (op0type);
+	      bool zextend_p = TYPE_UNSIGNED (op0type);
+	      this_optab = zextend_p ? umsub_widen_optab : smsub_widen_optab;
+	      if (mode == GET_MODE_2XWIDER_MODE (innermode)
+		  && (this_optab->handlers[(int) mode].insn_code
+		      != CODE_FOR_nothing))
+		{
+		  expand_operands (TREE_OPERAND (subsubexp0, 0),
+				   TREE_OPERAND (subsubexp1, 0),
+				   NULL_RTX, &op0, &op1, EXPAND_NORMAL);
+		  op2 = expand_expr (TREE_OPERAND (exp, 0), subtarget,
+				     VOIDmode, 0);
+		  temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
+					    target, unsignedp);
+		  gcc_assert (temp);
+		  return REDUCE_BIT_FIELD (temp);
+		}
+	    }
+	}
+
       /* For initializers, we are allowed to return a MINUS of two
 	 symbolic constants.  Here we handle all cases when both operands
 	 are constant.  */
Index: config/mips/mips-dspr2.md
===================================================================
--- config/mips/mips-dspr2.md	(revision 124503)
+++ config/mips/mips-dspr2.md	(working copy)
@@ -162,32 +162,14 @@
 	 (match_operand:DI 1 "register_operand")))]
   "TARGET_DSPR2 && !TARGET_64BIT")
 
-(define_insn "mips_msub"
-  [(set (match_operand:DI 0 "register_operand" "=a")
+(define_expand "mips_msub<u>"
+  [(set (match_operand:DI 0 "register_operand")
 	(minus:DI
-	 (match_operand:DI 1 "register_operand" "0")
-	 (mult:DI (sign_extend:DI
-		   (match_operand:SI 2 "register_operand" "d"))
-		  (sign_extend:DI
-		   (match_operand:SI 3 "register_operand" "d")))))]
-  "TARGET_DSPR2 && !TARGET_64BIT"
-  "msub\t%q0,%2,%3"
-  [(set_attr "type"	"imadd")
-   (set_attr "mode"	"SI")])
+	 (match_operand:DI 1 "register_operand")
+	 (mult:DI (any_extend:DI (match_operand:SI 2 "register_operand"))
+		  (any_extend:DI (match_operand:SI 3 "register_operand")))))]
+  "TARGET_DSPR2 && !TARGET_64BIT")
 
-(define_insn "mips_msubu"
-  [(set (match_operand:DI 0 "register_operand" "=a")
-	(minus:DI
-	 (match_operand:DI 1 "register_operand" "0")
-	 (mult:DI (zero_extend:DI
-		   (match_operand:SI 2 "register_operand" "d"))
-		  (zero_extend:DI
-		   (match_operand:SI 3 "register_operand" "d")))))]
-  "TARGET_DSPR2 && !TARGET_64BIT"
-  "msubu\t%q0,%2,%3"
-  [(set_attr "type"	"imadd")
-   (set_attr "mode"	"SI")])
-
 (define_insn "mulv2hi3"
   [(parallel
     [(set (match_operand:V2HI 0 "register_operand" "=d")
Index: config/mips/mips.md
===================================================================
--- config/mips/mips.md	(revision 124503)
+++ config/mips/mips.md	(working copy)
@@ -1649,16 +1649,18 @@
   [(set_attr "type" "imul")
    (set_attr "mode" "SI")])
 
-(define_insn "*msac<u>_di"
-  [(set (match_operand:DI 0 "register_operand" "=x")
+(define_insn "<u>msubsidi4"
+  [(set (match_operand:DI 0 "register_operand" "=ka")
         (minus:DI
 	   (match_operand:DI 3 "register_operand" "0")
 	   (mult:DI
 	      (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
 	      (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
-  "!TARGET_64BIT && ISA_HAS_MSAC"
+  "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || TARGET_DSPR2)"
 {
-  if (TARGET_MIPS5500)
+  if (TARGET_DSPR2)
+    return "msub<u>\t%q0,%1,%2";
+  else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
     return "msub<u>\t%1,%2";
   else
     return "msac<u>\t$0,%1,%2";

[-- Attachment #3: msub-1.c --]
[-- Type: application/octet-stream, Size: 356 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -march=vr5400 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsac\t\\\$0," 2 } } */

long long
f1 (int x, int y, long long z)
{
  return z - (long long) y * x;
}

long long
f2 (int x, int y, long long z)
{
  long long t = (long long) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #4: msub-2.c --]
[-- Type: application/octet-stream, Size: 350 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -march=vr5500 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsub\t" 2 } } */

long long
f1 (int x, int y, long long z)
{
  return z - (long long) y * x;
}

long long
f2 (int x, int y, long long z)
{
  long long t = (long long) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #5: msub-3.c --]
[-- Type: application/octet-stream, Size: 344 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -mips32 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsub\t" 2 } } */

long long
f1 (int x, int y, long long z)
{
  return z - (long long) y * x;
}

long long
f2 (int x, int y, long long z)
{
  long long t = (long long) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #6: msub-4.c --]
[-- Type: application/octet-stream, Size: 360 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -mips32r2 -mdspr2 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsub\t\\\$ac" 2 } } */

long long
f1 (int x, int y, long long z)
{
  return z - (long long) y * x;
}

long long
f2 (int x, int y, long long z)
{
  long long t = (long long) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #7: msubu-1.c --]
[-- Type: application/octet-stream, Size: 369 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -march=vr5400 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsacu\t\\\$0," 2 } } */

typedef unsigned int ui;
typedef unsigned long long ull;

ull
f1 (ui x, ui y, ull z)
{
  return z - (ull) y * x;
}

ull
f2 (ui x, ui y, ull z)
{
  ull t = (ull) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #8: msubu-2.c --]
[-- Type: application/octet-stream, Size: 363 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -march=vr5500 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsubu\t" 2 } } */

typedef unsigned int ui;
typedef unsigned long long ull;

ull
f1 (ui x, ui y, ull z)
{
  return z - (ull) y * x;
}

ull
f2 (ui x, ui y, ull z)
{
  ull t = (ull) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #9: msubu-3.c --]
[-- Type: application/octet-stream, Size: 357 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -mips32 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsubu\t" 2 } } */

typedef unsigned int ui;
typedef unsigned long long ull;

ull
f1 (ui x, ui y, ull z)
{
  return z - (ull) y * x;
}

ull
f2 (ui x, ui y, ull z)
{
  ull t = (ull) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

[-- Attachment #10: msubu-4.c --]
[-- Type: application/octet-stream, Size: 373 bytes --]

/* { dg-do compile } */
/* { dg-mips-options "-O2 -mips32r2 -mdspr2 -mgp32" } */
/* { dg-final { scan-assembler-times "\tmsubu\t\\\$ac" 2 } } */

typedef unsigned int ui;
typedef unsigned long long ull;

ull
f1 (ui x, ui y, ull z)
{
  return z - (ull) y * x;
}

ull
f2 (ui x, ui y, ull z)
{
  ull t = (ull) x * y;
  int temp = 5;
  if (temp == 5)
    z -= t;
  return z;
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFA] Patch to smsub_widen_optab & umsub_widen_optab
  2007-05-08  0:16 [RFA] Patch to smsub_widen_optab & umsub_widen_optab Fu, Chao-Ying
@ 2007-05-08  8:23 ` Richard Sandiford
  2007-05-08 22:31   ` Mark Mitchell
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Sandiford @ 2007-05-08  8:23 UTC (permalink / raw)
  To: Fu, Chao-Ying; +Cc: gcc-patches, Stephens, Nigel, Thekkath, Radhika

"Fu, Chao-Ying" <fu@mips.com> writes:
> 	* config/mips/mips.md (*msac<u>_di): Rename to...
> 	(<u>msubsidi4): ...this.  Extend condition to include
> 	GENERATE_MADD_MSUB and TARGET_DSPR2.  Change the constraint
> 	of operand 0 to "ka" and use the three-operand form of msub<u>
> 	for TARGET_DSPR2.
> 	* config/mips/mips-dspr2.md (mips_msub, mips_msubu): Convert
> 	to define_expands.

The MIPS parts are OK if the other bits are OK.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFA] Patch to smsub_widen_optab & umsub_widen_optab
  2007-05-08  8:23 ` Richard Sandiford
@ 2007-05-08 22:31   ` Mark Mitchell
  2007-05-08 23:04     ` Fu, Chao-Ying
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Mitchell @ 2007-05-08 22:31 UTC (permalink / raw)
  To: Fu, Chao-Ying, gcc-patches, Stephens, Nigel, Thekkath, Radhika, rsandifo

Richard Sandiford wrote:
> "Fu, Chao-Ying" <fu@mips.com> writes:
>> 	* config/mips/mips.md (*msac<u>_di): Rename to...
>> 	(<u>msubsidi4): ...this.  Extend condition to include
>> 	GENERATE_MADD_MSUB and TARGET_DSPR2.  Change the constraint
>> 	of operand 0 to "ka" and use the three-operand form of msub<u>
>> 	for TARGET_DSPR2.
>> 	* config/mips/mips-dspr2.md (mips_msub, mips_msubu): Convert
>> 	to define_expands.
> 
> The MIPS parts are OK if the other bits are OK.

The other bits are OK.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [RFA] Patch to smsub_widen_optab & umsub_widen_optab
  2007-05-08 22:31   ` Mark Mitchell
@ 2007-05-08 23:04     ` Fu, Chao-Ying
  0 siblings, 0 replies; 4+ messages in thread
From: Fu, Chao-Ying @ 2007-05-08 23:04 UTC (permalink / raw)
  To: Mark Mitchell, rsandifo, gcc-patches; +Cc: Stephens, Nigel, Thekkath, Radhika

> Richard Sandiford wrote:
> > "Fu, Chao-Ying" <fu@mips.com> writes:
> >> 	* config/mips/mips.md (*msac<u>_di): Rename to...
> >> 	(<u>msubsidi4): ...this.  Extend condition to include
> >> 	GENERATE_MADD_MSUB and TARGET_DSPR2.  Change the constraint
> >> 	of operand 0 to "ka" and use the three-operand form of msub<u>
> >> 	for TARGET_DSPR2.
> >> 	* config/mips/mips-dspr2.md (mips_msub, mips_msubu): Convert
> >> 	to define_expands.
> > 
> > The MIPS parts are OK if the other bits are OK.
> 
> The other bits are OK.
> 
> Thanks,
> 
> -- 
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713
> 

Thanks!  The patch is applied.

Regards,
Chao-ying

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-05-08 23:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-08  0:16 [RFA] Patch to smsub_widen_optab & umsub_widen_optab Fu, Chao-Ying
2007-05-08  8:23 ` Richard Sandiford
2007-05-08 22:31   ` Mark Mitchell
2007-05-08 23:04     ` Fu, Chao-Ying

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).