public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [fixed-point] Patch for saturating constant conversion and more documents
@ 2007-01-08 23:49 Fu, Chao-Ying
  0 siblings, 0 replies; only message in thread
From: Fu, Chao-Ying @ 2007-01-08 23:49 UTC (permalink / raw)
  To: gcc-patches; +Cc: Thekkath, Radhika, Stephens, Nigel

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

Hello,

  This patch updates constant conversions for saturating types,
documents *_FRACT_TYPE_SIZE and *_ACCUM_TYPE_SIZE in tm.texi,
and documents ADJUST_IBIT and ADJUST_FBIT in machmode.def.
Thanks a lot!

Ex: (satconvert.c)
     _Fract a = 2.5k;
_Sat _Fract b = 2.5k;

(satconvert.s)
        .file   1 "satconvert.c"
        .section .mdebug.eabi64
        .section .gcc_compiled_long64
        .previous
        .globl  a
        .section        .sdata,"aw",@progbits
        .align  2
        .type   a, @object
        .size   a, 4
a:
        .word   0x40000000
        .globl  b
        .align  2
        .type   b, @object
        .size   b, 4
b:
        .word   0x7fffffff
        .ident  "GCC: (GNU) 4.3.0 20070103 (experimental)"

Regards,
Chao-ying

2007-01-08  Chao-ying Fu  <fu@mips.com>

	* fixed-value.h (fixed_convert): Add one parameter of satp.
	* fixed-value.c (fixed_convert): Saturate the result when satp is true.
	* fold-const.c (fold_convert_const_fixed_from_fixed): Add one parameter
	in fixed_convert for saturating types.
	* machmode.def (ADJUST_IBIT, ADJUST_FBIT): Document.
	* doc/tm.texi (SHORT_FRACT_TYPE_SIZE, FRACT_TYPE_SIZE,
	LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE, SHORT_ACCUM_TYPE_SIZE,
	ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE, LONG_LONG_ACCUM_TYPE_SIZE):
	Document.

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

Index: fixed-value.h
===================================================================
--- fixed-value.h	(revision 120372)
+++ fixed-value.h	(working copy)
@@ -48,7 +48,7 @@
 
 /* Extend or truncate to a new mode.  */
 extern void fixed_convert (FIXED_VALUE_TYPE *, enum machine_mode,
-			   const FIXED_VALUE_TYPE *);
+			   const FIXED_VALUE_TYPE *, int);
 
 /* Compare two fixed-point objects for bitwise identity.  */
 extern bool fixed_identical (const FIXED_VALUE_TYPE *, const FIXED_VALUE_TYPE *);
Index: fixed-value.c
===================================================================
--- fixed-value.c	(revision 120372)
+++ fixed-value.c	(working copy)
@@ -668,30 +668,132 @@
     }
 }
 
-/* Extend or truncate to a new mode.  */
+/* Extend or truncate to a new mode.
+   If SATP, saturate the result to the max or the min.  */
 
 void
 fixed_convert (FIXED_VALUE_TYPE *f, enum machine_mode mode,
-               const FIXED_VALUE_TYPE *a)
+               const FIXED_VALUE_TYPE *a, int satp)
 {
   if (mode == a->mode)
-    *f = *a;
+    {
+      *f = *a;
+      return;
+    }
+    
+  if (GET_MODE_FBIT (mode) > GET_MODE_FBIT (a->mode))
+    {
+      /* Left shift a to temp_high, temp_low based on a->mode.  */
+      double_int temp_high, temp_low;
+      int amount = GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode);
+      lshift_double (a->data.low, a->data.high,
+		     amount,
+		     2 * HOST_BITS_PER_WIDE_INT,
+		     &temp_low.low, &temp_low.high,
+		     SIGNED_FIXED_POINT_MODE_P (a->mode));
+      /* Logical shift right to temp_high.  */
+      lshift_double (a->data.low, a->data.high,
+		     amount - 2 * HOST_BITS_PER_WIDE_INT,
+		     2 * HOST_BITS_PER_WIDE_INT,
+		     &temp_high.low, &temp_high.high, 0);
+      if (SIGNED_FIXED_POINT_MODE_P (a->mode)
+	  && a->data.high < 0) /* Signed-extend temp_high.  */
+	temp_high = double_int_ext (temp_high, amount, 0);
+      f->mode = mode;
+      f->data = temp_low;
+      if (satp)
+	{
+	  if (SIGNED_FIXED_POINT_MODE_P (a->mode) ==
+	      SIGNED_FIXED_POINT_MODE_P (f->mode))
+	    fixed_saturate2 (f->mode, temp_high, temp_low, &f->data);
+	  else
+	    {
+	      /* Take care of the cases when converting between
+		 signed and unsigned.  */
+	      if (SIGNED_FIXED_POINT_MODE_P (a->mode))
+		{
+		  /* Signed -> Unsigned.  */
+		  if (a->data.high < 0)
+		    {
+		      f->data.low = 0;  /* Set to zero.  */
+		      f->data.high = 0;  /* Set to zero.  */
+		    }
+		  else
+		    fixed_saturate2 (f->mode, temp_high, temp_low, &f->data);
+		}
+	      else
+		{
+		  /* Unsigned -> Signed.  */
+		  if (temp_high.high < 0)
+		    {
+		      /* Set to maximum.  */
+		      f->data.low = -1;  /* Set to all ones.  */
+		      f->data.high = -1;  /* Set to all ones.  */
+		      f->data = double_int_ext (f->data,
+						GET_MODE_FBIT (f->mode) +
+						GET_MODE_IBIT (f->mode),
+						1); /* Clear the sign.  */
+		    }
+		  else
+		    fixed_saturate2 (f->mode, temp_high, temp_low, &f->data);
+		}
+	    }
+	}
+    }
   else
     {
+      /* Right shift a to temp based on a->mode.  */
+      double_int temp;
+      lshift_double (a->data.low, a->data.high,
+		     GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode),
+		     2 * HOST_BITS_PER_WIDE_INT,
+		     &temp.low, &temp.high,
+		     SIGNED_FIXED_POINT_MODE_P (a->mode));
       f->mode = mode;
-      /* If fbit is not the same, we need to left or right shift data.  */
-      if (GET_MODE_FBIT (f->mode) != GET_MODE_FBIT (a->mode))
-	lshift_double (a->data.low, a->data.high,
-		       GET_MODE_FBIT (f->mode) - GET_MODE_FBIT (a->mode),
-		       2 * HOST_BITS_PER_WIDE_INT,
-		       &f->data.low, &f->data.high,
-		       SIGNED_FIXED_POINT_MODE_P (f->mode));
-      else
-	f->data = a->data;
-      f->data = double_int_ext (f->data,
-				SIGNED_FIXED_POINT_MODE_P (f->mode)
-				+ GET_MODE_FBIT (f->mode)
-				+ GET_MODE_IBIT (f->mode),
-				UNSIGNED_FIXED_POINT_MODE_P (f->mode));
+      f->data = temp;
+      if (satp)
+	{
+	  if (SIGNED_FIXED_POINT_MODE_P (a->mode) ==
+	      SIGNED_FIXED_POINT_MODE_P (f->mode))
+	    fixed_saturate1 (f->mode, f->data, &f->data);
+	  else
+	    {
+	      /* Take care of the cases when converting between
+		 signed and unsigned.  */
+	      if (SIGNED_FIXED_POINT_MODE_P (a->mode))
+		{
+		  /* Signed -> Unsigned.  */
+		  if (a->data.high < 0)
+		    {
+		      f->data.low = 0;  /* Set to zero.  */
+		      f->data.high = 0;  /* Set to zero.  */
+		    }
+		  else
+		    fixed_saturate1 (f->mode, f->data, &f->data);
+		}
+	      else
+		{
+		  /* Unsigned -> Signed.  */
+		  if (temp.high < 0)
+		    {
+		      /* Set to maximum.  */
+		      f->data.low = -1;  /* Set to all ones.  */
+		      f->data.high = -1;  /* Set to all ones.  */
+		      f->data = double_int_ext (f->data,
+						GET_MODE_FBIT (f->mode) +
+						GET_MODE_IBIT (f->mode),
+						1); /* Clear the sign.  */
+		    }
+		  else
+		    fixed_saturate1 (f->mode, f->data, &f->data);
+		}
+	    }
+	}
     }
+
+  f->data = double_int_ext (f->data,
+			    SIGNED_FIXED_POINT_MODE_P (f->mode)
+			    + GET_MODE_FBIT (f->mode)
+			    + GET_MODE_IBIT (f->mode),
+			    UNSIGNED_FIXED_POINT_MODE_P (f->mode));
 }
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 120377)
+++ fold-const.c	(working copy)
@@ -2032,7 +2032,8 @@
   FIXED_VALUE_TYPE value;
   tree t;
 
-  fixed_convert (&value, TYPE_MODE (type), &TREE_FIXED_CST (arg1));
+  fixed_convert (&value, TYPE_MODE (type), &TREE_FIXED_CST (arg1),
+		 TYPE_SATURATING (type));
   t = build_fixed (type, value);
 
   return t;
Index: machmode.def
===================================================================
--- machmode.def	(revision 120372)
+++ machmode.def	(working copy)
@@ -151,10 +151,12 @@
      ADJUST_BYTESIZE (MODE, EXPR);
      ADJUST_ALIGNMENT (MODE, EXPR);
      ADJUST_FLOAT_FORMAT (MODE, EXPR);
-        Arrange for the byte size, alignment, or floating point format
-	of MODE to be adjustable at run time.  EXPR will be executed
+     ADJUST_IBIT (MODE, EXPR);
+     ADJUST_FBIT (MODE, EXPR);
+        Arrange for the byte size, alignment, floating point format, ibit,
+	or fbit of MODE to be adjustable at run time.  EXPR will be executed
 	once after processing all command line options, and should
-	evaluate to the desired byte size, alignment, or format.
+	evaluate to the desired byte size, alignment, format, ibit or fbit.
 
 	Unlike a FORMAT argument, if you are adjusting a float format
 	you must put an & in front of the name of each format structure.
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 120376)
+++ doc/tm.texi	(working copy)
@@ -1549,6 +1549,54 @@
 words.
 @end defmac
 
+@defmac SHORT_FRACT_TYPE_SIZE
+A C expression for the size in bits of the type @code{short _Fract} on
+the target machine.  If you don't define this, the default is half a
+word.
+@end defmac
+
+@defmac FRACT_TYPE_SIZE
+A C expression for the size in bits of the type @code{_Fract} on
+the target machine.  If you don't define this, the default is one
+word.
+@end defmac
+
+@defmac LONG_FRACT_TYPE_SIZE
+A C expression for the size in bits of the type @code{long _Fract} on
+the target machine.  If you don't define this, the default is two
+words.
+@end defmac
+
+@defmac LONG_LONG_FRACT_TYPE_SIZE
+A C expression for the size in bits of the type @code{long long _Fract} on
+the target machine.  If you don't define this, the default is four
+words.
+@end defmac
+
+@defmac SHORT_ACCUM_TYPE_SIZE
+A C expression for the size in bits of the type @code{short _Accum} on
+the target machine.  If you don't define this, the default is one
+word.
+@end defmac
+
+@defmac ACCUM_TYPE_SIZE
+A C expression for the size in bits of the type @code{_Accum} on
+the target machine.  If you don't define this, the default is two
+words.
+@end defmac
+
+@defmac LONG_ACCUM_TYPE_SIZE
+A C expression for the size in bits of the type @code{long _Accum} on
+the target machine.  If you don't define this, the default is four
+words.
+@end defmac
+
+@defmac LONG_LONG_ACCUM_TYPE_SIZE
+A C expression for the size in bits of the type @code{long long _Accum} on
+the target machine.  If you don't define this, the default is four
+words.
+@end defmac
+
 @defmac LIBGCC2_LONG_DOUBLE_TYPE_SIZE
 Define this macro if @code{LONG_DOUBLE_TYPE_SIZE} is not constant or
 if you want routines in @file{libgcc2.a} for a size other than

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-01-08 23:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-08 23:49 [fixed-point] Patch for saturating constant conversion and more documents 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).