[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-gnulib] more porting of code containing >> to Crays
From: |
Paul Eggert |
Subject: |
[Bug-gnulib] more porting of code containing >> to Crays |
Date: |
Wed, 10 Nov 2004 22:21:29 -0800 |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) |
Inspired by the recent changes to mktime.c for right-shift on Crays, I
installed similar changes to getdate.y, strftime.c, and quotearg.c.
This is both for gnulib and for coreutils:
2004-11-10 Paul Eggert <address@hidden>
* lib/getdate.y (SHR): New macro, which is a portable
substitute for >> that should work even on Crays.
(tm_diff): Use it.
* lib/strftime.c (SHR): Likewise.
(tm_diff): Use it.
* lib/quotearg.c (struct quoting_options): Use unsigned int for
quote_these_too, so that right shifts are well defined. All uses
changed.
Index: lib/getdate.y
===================================================================
RCS file: /fetish/cu/lib/getdate.y,v
retrieving revision 1.88
diff -p -u -r1.88 getdate.y
--- lib/getdate.y 3 Nov 2004 08:54:51 -0000 1.88
+++ lib/getdate.y 11 Nov 2004 05:49:17 -0000
@@ -84,6 +84,21 @@
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#endif
+/* Shift A right by B bits portably, by dividing A by 2**B and
+ truncating towards minus infinity. A and B should be free of side
+ effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
+ INT_BITS is the number of useful bits in an int. GNU code can
+ assume that INT_BITS is at least 32.
+
+ ISO C99 says that A >> B is implementation-defined if A < 0. Some
+ implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
+ right in the usual way when A < 0, so SHR falls back on division if
+ ordinary A >> B doesn't seem to be the usual signed shift. */
+#define SHR(a, b) \
+ (-1 >> 1 == -1 \
+ ? (a) >> (b) \
+ : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
+
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
@@ -734,12 +749,12 @@ tm_diff (struct tm const *a, struct tm c
{
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid int overflow in leap day calculations. */
- int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
- int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+ int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
+ int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
int a100 = a4 / 25 - (a4 % 25 < 0);
int b100 = b4 / 25 - (b4 % 25 < 0);
- int a400 = a100 >> 2;
- int b400 = b100 >> 2;
+ int a400 = SHR (a100, 2);
+ int b400 = SHR (b100, 2);
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
long int ayear = a->tm_year;
long int years = ayear - b->tm_year;
Index: lib/strftime.c
===================================================================
RCS file: /fetish/cu/lib/strftime.c,v
retrieving revision 1.77
diff -p -u -r1.77 strftime.c
--- lib/strftime.c 9 Nov 2004 20:54:43 -0000 1.77
+++ lib/strftime.c 11 Nov 2004 05:49:17 -0000
@@ -104,6 +104,21 @@ extern char *tzname[];
# endif
#endif
+/* Shift A right by B bits portably, by dividing A by 2**B and
+ truncating towards minus infinity. A and B should be free of side
+ effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
+ INT_BITS is the number of useful bits in an int. GNU code can
+ assume that INT_BITS is at least 32.
+
+ ISO C99 says that A >> B is implementation-defined if A < 0. Some
+ implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
+ right in the usual way when A < 0, so SHR falls back on division if
+ ordinary A >> B doesn't seem to be the usual signed shift. */
+#define SHR(a, b) \
+ (-1 >> 1 == -1 \
+ ? (a) >> (b) \
+ : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
+
#define TYPE_SIGNED(t) ((t) -1 < 0)
/* Bound on length of the string representing an integer value of type t.
@@ -279,12 +294,12 @@ tm_diff (const struct tm *a, const struc
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid int overflow in leap day calculations,
but it's OK to assume that A and B are close to each other. */
- int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
- int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+ int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
+ int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
int a100 = a4 / 25 - (a4 % 25 < 0);
int b100 = b4 / 25 - (b4 % 25 < 0);
- int a400 = a100 >> 2;
- int b400 = b100 >> 2;
+ int a400 = SHR (a100, 2);
+ int b400 = SHR (b100, 2);
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
int years = a->tm_year - b->tm_year;
int days = (365 * years + intervening_leap_days
Index: lib/quotearg.c
===================================================================
RCS file: /fetish/cu/lib/quotearg.c,v
retrieving revision 1.43
diff -p -u -r1.43 quotearg.c
--- lib/quotearg.c 2 Aug 2004 22:52:17 -0000 1.43
+++ lib/quotearg.c 11 Nov 2004 05:49:17 -0000
@@ -84,7 +84,7 @@ struct quoting_options
/* Quote the characters indicated by this bit vector even if the
quoting style would not normally require them to be quoted. */
- int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
+ unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
};
/* Names of quoting styles. */
@@ -152,7 +152,8 @@ int
set_char_quoting (struct quoting_options *o, char c, int i)
{
unsigned char uc = c;
- int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
+ unsigned int *p =
+ (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
int shift = uc % INT_BITS;
int r = (*p >> shift) & 1;
*p ^= ((i & 1) ^ r) << shift;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug-gnulib] more porting of code containing >> to Crays,
Paul Eggert <=