re PR fortran/31964 ([4.2, 4.1 only]ishftc fails with certain thrid argument)

2007-05-18  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libfortran/31964
	* intrinsics/ishftc.c (ishftc4, ishftc8, ishftc16): Fix mask to handle
	shift of bit-size number of bits.

From-SVN: r124846
This commit is contained in:
Jerry DeLisle 2007-05-19 01:04:03 +00:00
parent cc25a1c458
commit c152efbb10
2 changed files with 33 additions and 15 deletions

View File

@ -1,3 +1,9 @@
2007-05-18 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/31964
* intrinsics/ishftc.c (ishftc4, ishftc8, ishftc16): Fix mask to handle
shift of bit-size number of bits.
2007-05-17 Tobias Burnus <burnus@net-b.de>
PR fortran/31917

View File

@ -36,8 +36,7 @@ export_proto(ishftc4);
GFC_INTEGER_4
ishftc4 (GFC_INTEGER_4 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
{
GFC_INTEGER_4 mask;
GFC_UINTEGER_4 bits;
GFC_UINTEGER_4 mask, bits;
if (shift < 0)
shift = shift + size;
@ -45,9 +44,14 @@ ishftc4 (GFC_INTEGER_4 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
if (shift == 0 || shift == size)
return i;
mask = (~(GFC_INTEGER_4)0) << size;
bits = i & ~mask;
return (i & mask) | (bits >> (size - shift)) | ((i << shift) & ~mask);
/* In C, the result of the shift operator is undefined if the right operand
is greater than or equal to the number of bits in the left operand. So we
have to special case it for fortran. */
mask = ~((size == 32) ? (GFC_UINTEGER_4)0 : (~(GFC_UINTEGER_4)0 << size));
bits = i & mask;
return (i & ~mask) | ((bits << shift) & mask) | (bits >> (size - shift));
}
extern GFC_INTEGER_8 ishftc8 (GFC_INTEGER_8, GFC_INTEGER_4, GFC_INTEGER_4);
@ -56,8 +60,7 @@ export_proto(ishftc8);
GFC_INTEGER_8
ishftc8 (GFC_INTEGER_8 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
{
GFC_INTEGER_8 mask;
GFC_UINTEGER_8 bits;
GFC_UINTEGER_8 mask, bits;
if (shift < 0)
shift = shift + size;
@ -65,9 +68,14 @@ ishftc8 (GFC_INTEGER_8 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
if (shift == 0 || shift == size)
return i;
mask = (~(GFC_INTEGER_8)0) << size;
bits = i & ~mask;
return (i & mask) | (bits >> (size - shift)) | ((i << shift) & ~mask);
/* In C, the result of the shift operator is undefined if the right operand
is greater than or equal to the number of bits in the left operand. So we
have to special case it for fortran. */
mask = ~((size == 64) ? (GFC_UINTEGER_8)0 : (~(GFC_UINTEGER_8)0 << size));
bits = i & mask;
return (i & ~mask) | ((bits << shift) & mask) | (bits >> (size - shift));
}
#ifdef HAVE_GFC_INTEGER_16
@ -77,8 +85,7 @@ export_proto(ishftc16);
GFC_INTEGER_16
ishftc16 (GFC_INTEGER_16 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
{
GFC_INTEGER_16 mask;
GFC_UINTEGER_16 bits;
GFC_UINTEGER_16 mask, bits;
if (shift < 0)
shift = shift + size;
@ -86,8 +93,13 @@ ishftc16 (GFC_INTEGER_16 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
if (shift == 0 || shift == size)
return i;
mask = (~(GFC_INTEGER_16)0) << size;
bits = i & ~mask;
return (i & mask) | (bits >> (size - shift)) | ((i << shift) & ~mask);
/* In C, the result of the shift operator is undefined if the right operand
is greater than or equal to the number of bits in the left operand. So we
have to special case it for fortran. */
mask = ~((size == 128) ? (GFC_UINTEGER_16)0 : (~(GFC_UINTEGER_16)0 << size));
bits = i & mask;
return (i & ~mask) | ((bits << shift) & mask) | (bits >> (size - shift));
}
#endif