Subject: gcc/egcs problem with shifts on i386
To: None <current-users@netbsd.org>
From: Colin Wood <cwood@ichips.intel.com>
List: current-users
Date: 08/16/1999 21:00:47
i wrote a little program to play with shifts today (i needed it for work)
and discovered a problem with shifts under i386 (or IA32 as we like to say
here at work ;-) the program is included below for reference. what i've
found is that if i specify a shift count of 32 for either a right or left
shift (i.e num << 32), i get back the same number i put in, rather than a
0. for example:
<nb00:ender>/home/ender/junk% ./shift l 0x7fffffff 32
shl 0x7fffffff, 0x20 -> 0x7fffffff
<nb00:ender>/home/ender/junk% ./shift l 0x7fffffff 31
shl 0x7fffffff, 0x1f -> 0x80000000
<nb00:ender>/home/ender/junk% ./shift r 0x7fffffff 31
shr 0x7fffffff, 0x1f -> 0x0
<nb00:ender>/home/ender/junk% ./shift r 0x7fffffff 32
shr 0x7fffffff, 0x20 -> 0x7fffffff
this only appears to occur on i386 (and i can probably explain it fairly
easily if a shift is implemented via SHL/SHR). what i'm wondering is if
this is a bug in egcs/gcc, or if this is simply a hole in the C spec and
either behavior is allowed.
anyone know?
later.
colin
--
Colin Wood cwood@ichips.intel.com
Component Design Engineer - PMD Intel Corporation
-----------------------------------------------------------------
I speak only on my own behalf, not for my employer.
#include<stdio.h>
#include<stdlib.h>
int
main(int argc, char *argv[])
{
long in, shift, out;
char dir;
if (argc != 4) {
fprintf(stderr, "Usage: shift <dir> <number> <shift count>\n");
exit(-1);
}
dir = *(argv[1]);
in = strtoul(argv[2], NULL, 0);
shift = strtoul(argv[3], NULL, 0);
switch (dir) {
case 'l':
out = in << shift;
break;
case 'r':
out = in >> shift;
break;
}
fprintf(stdout, "sh%c 0x%x, 0x%x -> 0x%x\n", dir, in, shift, out);
return (0);
}