* [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).