/*
Summary:  This program compiles and runs correctly on my fedora core 6
system.  On the fedora core 11 system, the function "bad11" produces
incorrect code as pointed out below.  This is repaired in the funcdtion
"good11", which avoides using the ..._bit macros (asm/bitops.h).

I have included an exerpt of disassembled code from "bad11" with some
of the errors pointed out (just above "bad11"), and results obtained on
the fedora core 11 system (in the main function).
I have attached bug11.i (gcc output) and bug11.x (stdout and stderr from
the gcc command) to the end of this source file.

Program build to make bug11.i and bug11.x:
gcc -v -save-temps -O -Wall -o bug11 bug11.c &> bug11.x
Program build to make a testable exe:
gcc -g -O -Wall -o bug11 bug11.c &> bug11.x

// The fedora core 11 installation on Toshiba A65, done using
// Fedora-11-i386-DVD.iso:
$ gcc --version
gcc (GCC) 4.4.0 20090506 (Red Hat 4.4.0-4)
$ uname -a
Linux localhost.localdomain 2.6.29.4-167.fc11.i686.PAE #1 SMP Wed May 27
17:28:22 EDT 2009 i686 i686 i386 GNU/Linux

*************** Note this error when starting gdb on the f.c.11 system:
$ gdb bug11
GNU gdb (GDB) Fedora (6.8.50.20090302-21.fc11)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i586-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
(gdb) b main
Breakpoint 1 at 0x804859a: file bug11.c, line 112.
(gdb) r
Starting program: /tmp/bug11

Breakpoint 1, main () at bug11.c:112
112       memcpy( xy_good, xy, sizeof(xy_good) );
Missing separate debuginfos, use: debuginfo-install glibc-2.10.1-2.i686
***************

The fedora core 6 system on a Dell Latitude D510:
-bash-3.1$ gcc --version
gcc (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)
-bash-3.1$ uname -a
Linux tiger 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:37:32 EDT 2006 i686 i686
i386 GNU/Linux
*/

#include <string.h>

// from <asm/bitops.h>
#define ADDR (*(volatile long *) addr)
static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
        int oldbit;

        __asm__ __volatile__(
                "btrl %2,%1\n\tsbbl %0,%0"
                :"=r" (oldbit),"=m" (ADDR)
                :"Ir" (nr) : "memory");
        return oldbit;
}
static __inline__ void set_bit(int nr, volatile void * addr)
{
        __asm__ __volatile__(
                "btsl %1,%0"
                :"=m" (ADDR)
                :"Ir" (nr));
}

// This makes correct code.  It takes a series of x,y screen coordinate
// pairs and applies limits and offset values to put the graph where desired.
void good11( int how, unsigned numpoints, unsigned short *points,
              unsigned short hix, unsigned short hiy,
              unsigned short orgx, unsigned short orgy )
{
  unsigned short xx, yy, penbit;

  for ( ;  numpoints;  numpoints--, points += 2 ) {
    xx = points[0];
    penbit = xx & 0x8000;  xx &= 0x7fff;
    yy = points[1];
    if ( xx > hix ) {
      if ( how == 0 )  xx = hix;
      else if ( how == 1 ) xx = 0;
      else do { xx -= hix; } while ( xx > hix );
    }
    xx += orgx;
    if ( yy > hiy ) {
      if ( how == 0 ) yy = hiy;
      else if ( how == 1 ) yy = 0;
      else do { yy -= hiy; } while ( yy > hiy );
    }
    yy += orgy;
    points[0] = xx | penbit;  points[1] = yy;
  }
}

/* bad on fedora core 11-- in disassembled code, the 'for' loop starts like
this:
0x080484bb <bad11+36>:  cmpl   $0x0,0xc(%ebp)
0x080484bf <bad11+40>:  je     0x8048589 <bad11+242>
0x080484c5 <bad11+46>:  mov    %ebx,%edi
0x080484c7 <bad11+48>:  neg    %edi
0x080484c9 <bad11+50>:  mov    %di,-0x22(%ebp)
0x080484cd <bad11+54>:  mov    %si,-0x2c(%ebp)
0x080484d1 <bad11+58>:  mov    %esi,%eax
0x080484d3 <bad11+60>:  neg    %eax
0x080484d5 <bad11+62>:  mov    %ax,-0x24(%ebp)
       'for' jumps back to here; the variable at -0xe(%ebp) is
       getting used before it is set, so the value is from the
       previous pass thru the loop
       also, %edx is indexing the data array, but there is no
       load of data from (%edx) (the xx value) although there is
       from 2(%edx) (the yy value)
0x080484d9 <test_and_clear_bit+0>:      btrl   $0xf,-0xe(%ebp)
0x080484de <test_and_clear_bit+5>:      sbb    %ecx,%ecx
0x080484e0 <test_and_clear_bit+7>:      mov    %ecx,-0x20(%ebp)
0x080484e3 <bad11+76>:  movzwl 0x2(%edx),%eax
0x080484e7 <bad11+80>:  movzwl -0xe(%ebp),%ecx
0x080484eb <bad11+84>:  cmp    %bx,%cx
0x080484ee <bad11+87>:  jbe    0x8048527 <bad11+144>
0x080484f0 <bad11+89>:  cmpl   $0x0,0x8(%ebp)
0x080484f4 <bad11+93>:  jne    0x80484fc <bad11+101>
0x080484f6 <bad11+95>:  mov    %bx,-0xe(%ebp)
*/
void bad11( int how, unsigned numpoints, unsigned short *points,
            unsigned short hix, unsigned short hiy,
            unsigned short orgx, unsigned short orgy )
{
  unsigned short xx, yy;
  int penbit;

  for ( ;  numpoints;  numpoints--, points += 2 ) {
    xx = points[0];  penbit = test_and_clear_bit( 15, (void *)&xx );
    yy = points[1];
    if ( xx > hix ) {
      if ( how == 0 )  xx = hix;
      else if ( how == 1 ) xx = 0;
      else do { xx -= hix; } while ( xx > hix );
    }
    xx += orgx;
    if ( yy > hiy ) {
      if ( how == 0 ) yy = hiy;
      else if ( how == 1 ) yy = 0;
      else do { yy -= hiy; } while ( yy > hiy );
    }
    yy += orgy;
    if ( penbit ) set_bit( 15, (void *)&xx );
    points[0] = xx;  points[1] = yy;
  }
}

unsigned short xy[20] = { 0,0, 0x8010,0x10, 0x100,0x100, 0x8200,0x200,
0x300,0x300, 0x8400,0x400, 0x500,0x500, 0x8600,0x600, 0x700,0x700, 0x8800,0x800
};
unsigned short xy_good[20], xy_bad[20];

int main( void )
{
  memcpy( xy_good, xy, sizeof(xy_good) );
  good11( 0, 10, xy_good, 0x550, 0x550, 0, 0 );
  memcpy( xy_bad, xy, sizeof(xy_good) );
  bad11( 0, 10, xy_bad, 0x550, 0x550, 0, 0 );
/*
(gdb) p /x xy
$1 = { 0x0000, 0x0000,  0x8010, 0x0010,  0x0100, 0x0100,  0x8200, 0x0200, 
0x0300, 0x0300,
       0x8400, 0x0400,  0x0500, 0x0500,  0x8600, 0x0600,  0x0700, 0x0700, 
0x8800, 0x0800 }
(gdb) p /x xy_good
$2 = { 0x0000, 0x0000,  0x8010, 0x0010,  0x0100, 0x0100,  0x8200, 0x0200, 
0x0300, 0x0300,
       0x8400, 0x0400,  0x0500, 0x0500,  0x8550, 0x0550,  0x0550, 0x0550, 
0x8550, 0x0550 }
(gdb) p /x xy_bad       # from f.c.11  (on f.c.6 it is the same as xy_good)
$3 = { 0x8550, 0x0000,  0x8550, 0x0010,  0x8550, 0x0100,  0x8550, 0x0200, 
0x8550, 0x0300,
       0x8550, 0x0400,  0x8550, 0x0500,  0x8550, 0x0550,  0x8550, 0x0550, 
0x8550, 0x0550 }
*/
  memcpy( xy_good, xy, sizeof(xy_good) );
  good11( 0, 10, xy_good, 0x550, 0x550, 0x111, 0x222 );
  memcpy( xy_bad, xy, sizeof(xy_good) );
  bad11( 0, 10, xy_bad, 0x550, 0x550, 0x111, 0x222 );
/*
(gdb) p /x xy
$4 = { 0x0000, 0x0000,  0x8010, 0x0010,  0x0100, 0x0100,  0x8200, 0x0200, 
0x0300, 0x0300,
       0x8400, 0x0400,  0x0500, 0x0500,  0x8600, 0x0600,  0x0700, 0x0700, 
0x8800, 0x0800 }
(gdb) p /x xy_good
$5 = { 0x0111, 0x0222,  0x8121, 0x0232,  0x0211, 0x0322,  0x8311, 0x0422, 
0x0411, 0x0522,
       0x8511, 0x0622,  0x0611, 0x0722,  0x8661, 0x0772,  0x0661, 0x0772, 
0x8661, 0x0772 }
(gdb) p /x xy_bad       # from f.c.11  (on f.c.6 it is the same as xy_good)
$6 = { 0x8661, 0x0222,  0x8661, 0x0232,  0x8661, 0x0322,  0x8661, 0x0422, 
0x8661, 0x0522,
       0x8661, 0x0622,  0x8661, 0x0722,  0x8661, 0x0772,  0x8661, 0x0772, 
0x8661, 0x0772 }
*/
  return 0;
}


END OF SOURCE FILE

-----------------------bug11.i (output file from gcc -v -save-temps....)
# 1 "bug11.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "bug11.c"
# 51 "bug11.c"
# 1 "/usr/include/string.h" 1 3 4
# 26 "/usr/include/string.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 352 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 365 "/usr/include/sys/cdefs.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 366 "/usr/include/sys/cdefs.h" 2 3 4
# 353 "/usr/include/features.h" 2 3 4
# 376 "/usr/include/features.h" 3 4
# 1 "/usr/include/gnu/stubs.h" 1 3 4



# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 5 "/usr/include/gnu/stubs.h" 2 3 4


# 1 "/usr/include/gnu/stubs-32.h" 1 3 4
# 8 "/usr/include/gnu/stubs.h" 2 3 4
# 377 "/usr/include/features.h" 2 3 4
# 27 "/usr/include/string.h" 2 3 4






# 1 "/usr/lib/gcc/i586-redhat-linux/4.4.0/include/stddef.h" 1 3 4
# 211 "/usr/lib/gcc/i586-redhat-linux/4.4.0/include/stddef.h" 3 4
typedef unsigned int size_t;
# 34 "/usr/include/string.h" 2 3 4









extern void *memcpy (void *__restrict __dest,
       __const void *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern void *memmove (void *__dest, __const void *__src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));






extern void *memccpy (void *__restrict __dest, __const void *__restrict __src,
        int __c, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));





extern void *memset (void *__s, int __c, size_t __n) __attribute__
((__nothrow__)) __attribute__ ((__nonnull__ (1)));


extern int memcmp (__const void *__s1, __const void *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));
# 94 "/usr/include/string.h" 3 4
extern void *memchr (__const void *__s, int __c, size_t __n)
      __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));


# 125 "/usr/include/string.h" 3 4


extern char *strcpy (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));

extern char *strncpy (char *__restrict __dest,
        __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern char *strcat (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));

extern char *strncat (char *__restrict __dest, __const char *__restrict __src,
        size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__
(1, 2)));


extern int strcmp (__const char *__s1, __const char *__s2)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));

extern int strncmp (__const char *__s1, __const char *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));


extern int strcoll (__const char *__s1, __const char *__s2)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));

extern size_t strxfrm (char *__restrict __dest,
         __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2)));






# 1 "/usr/include/xlocale.h" 1 3 4
# 28 "/usr/include/xlocale.h" 3 4
typedef struct __locale_struct
{

  struct locale_data *__locales[13];


  const unsigned short int *__ctype_b;
  const int *__ctype_tolower;
  const int *__ctype_toupper;


  const char *__names[13];
} *__locale_t;


typedef __locale_t locale_t;
# 162 "/usr/include/string.h" 2 3 4


extern int strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2, 3)));

extern size_t strxfrm_l (char *__dest, __const char *__src, size_t __n,
    __locale_t __l) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__
(2, 4)));




extern char *strdup (__const char *__s)
     __attribute__ ((__nothrow__)) __attribute__ ((__malloc__)) __attribute__
((__nonnull__ (1)));






extern char *strndup (__const char *__string, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__malloc__)) __attribute__
((__nonnull__ (1)));
# 208 "/usr/include/string.h" 3 4

# 233 "/usr/include/string.h" 3 4
extern char *strchr (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));
# 260 "/usr/include/string.h" 3 4
extern char *strrchr (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));


# 279 "/usr/include/string.h" 3 4



extern size_t strcspn (__const char *__s, __const char *__reject)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));


extern size_t strspn (__const char *__s, __const char *__accept)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));
# 312 "/usr/include/string.h" 3 4
extern char *strpbrk (__const char *__s, __const char *__accept)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));
# 340 "/usr/include/string.h" 3 4
extern char *strstr (__const char *__haystack, __const char *__needle)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));




extern char *strtok (char *__restrict __s, __const char *__restrict __delim)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2)));




extern char *__strtok_r (char *__restrict __s,
    __const char *__restrict __delim,
    char **__restrict __save_ptr)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2, 3)));

extern char *strtok_r (char *__restrict __s, __const char *__restrict __delim,
         char **__restrict __save_ptr)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2, 3)));
# 395 "/usr/include/string.h" 3 4


extern size_t strlen (__const char *__s)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));





extern size_t strnlen (__const char *__string, size_t __maxlen)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));





extern char *strerror (int __errnum) __attribute__ ((__nothrow__));

# 425 "/usr/include/string.h" 3 4
extern int strerror_r (int __errnum, char *__buf, size_t __buflen) __asm__ (""
"__xpg_strerror_r") __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__
(2)));
# 443 "/usr/include/string.h" 3 4
extern char *strerror_l (int __errnum, __locale_t __l) __attribute__
((__nothrow__));





extern void __bzero (void *__s, size_t __n) __attribute__ ((__nothrow__))
__attribute__ ((__nonnull__ (1)));



extern void bcopy (__const void *__src, void *__dest, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern void bzero (void *__s, size_t __n) __attribute__ ((__nothrow__))
__attribute__ ((__nonnull__ (1)));


extern int bcmp (__const void *__s1, __const void *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));
# 487 "/usr/include/string.h" 3 4
extern char *index (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));
# 515 "/usr/include/string.h" 3 4
extern char *rindex (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1)));




extern int ffs (int __i) __attribute__ ((__nothrow__)) __attribute__
((__const__));
# 534 "/usr/include/string.h" 3 4
extern int strcasecmp (__const char *__s1, __const char *__s2)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));


extern int strncasecmp (__const char *__s1, __const char *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__
((__nonnull__ (1, 2)));
# 557 "/usr/include/string.h" 3 4
extern char *strsep (char **__restrict __stringp,
       __const char *__restrict __delim)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));




extern char *strsignal (int __sig) __attribute__ ((__nothrow__));


extern char *__stpcpy (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *stpcpy (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));



extern char *__stpncpy (char *__restrict __dest,
   __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *stpncpy (char *__restrict __dest,
        __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
# 632 "/usr/include/string.h" 3 4
# 1 "/usr/include/bits/string.h" 1 3 4
# 633 "/usr/include/string.h" 2 3 4


# 1 "/usr/include/bits/string2.h" 1 3 4
# 52 "/usr/include/bits/string2.h" 3 4
# 1 "/usr/include/endian.h" 1 3 4
# 37 "/usr/include/endian.h" 3 4
# 1 "/usr/include/bits/endian.h" 1 3 4
# 38 "/usr/include/endian.h" 2 3 4
# 61 "/usr/include/endian.h" 3 4
# 1 "/usr/include/bits/byteswap.h" 1 3 4
# 62 "/usr/include/endian.h" 2 3 4
# 53 "/usr/include/bits/string2.h" 2 3 4
# 1 "/usr/include/bits/types.h" 1 3 4
# 28 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 29 "/usr/include/bits/types.h" 2 3 4


typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;


typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;




__extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t;







__extension__ typedef long long int __quad_t;
__extension__ typedef unsigned long long int __u_quad_t;
# 131 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/typesizes.h" 1 3 4
# 132 "/usr/include/bits/types.h" 2 3 4


__extension__ typedef __u_quad_t __dev_t;
__extension__ typedef unsigned int __uid_t;
__extension__ typedef unsigned int __gid_t;
__extension__ typedef unsigned long int __ino_t;
__extension__ typedef __u_quad_t __ino64_t;
__extension__ typedef unsigned int __mode_t;
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int __off_t;
__extension__ typedef __quad_t __off64_t;
__extension__ typedef int __pid_t;
__extension__ typedef struct { int __val[2]; } __fsid_t;
__extension__ typedef long int __clock_t;
__extension__ typedef unsigned long int __rlim_t;
__extension__ typedef __u_quad_t __rlim64_t;
__extension__ typedef unsigned int __id_t;
__extension__ typedef long int __time_t;
__extension__ typedef unsigned int __useconds_t;
__extension__ typedef long int __suseconds_t;

__extension__ typedef int __daddr_t;
__extension__ typedef long int __swblk_t;
__extension__ typedef int __key_t;


__extension__ typedef int __clockid_t;


__extension__ typedef void * __timer_t;


__extension__ typedef long int __blksize_t;




__extension__ typedef long int __blkcnt_t;
__extension__ typedef __quad_t __blkcnt64_t;


__extension__ typedef unsigned long int __fsblkcnt_t;
__extension__ typedef __u_quad_t __fsblkcnt64_t;


__extension__ typedef unsigned long int __fsfilcnt_t;
__extension__ typedef __u_quad_t __fsfilcnt64_t;

__extension__ typedef int __ssize_t;



typedef __off64_t __loff_t;
typedef __quad_t *__qaddr_t;
typedef char *__caddr_t;


__extension__ typedef int __intptr_t;


__extension__ typedef unsigned int __socklen_t;
# 54 "/usr/include/bits/string2.h" 2 3 4
# 394 "/usr/include/bits/string2.h" 3 4
extern void *__rawmemchr (const void *__s, int __c);
# 969 "/usr/include/bits/string2.h" 3 4
extern __inline size_t __strcspn_c1 (__const char *__s, int __reject);
extern __inline size_t
__strcspn_c1 (__const char *__s, int __reject)
{
  register size_t __result = 0;
  while (__s[__result] != '\0' && __s[__result] != __reject)
    ++__result;
  return __result;
}

extern __inline size_t __strcspn_c2 (__const char *__s, int __reject1,
         int __reject2);
extern __inline size_t
__strcspn_c2 (__const char *__s, int __reject1, int __reject2)
{
  register size_t __result = 0;
  while (__s[__result] != '\0' && __s[__result] != __reject1
  && __s[__result] != __reject2)
    ++__result;
  return __result;
}

extern __inline size_t __strcspn_c3 (__const char *__s, int __reject1,
         int __reject2, int __reject3);
extern __inline size_t
__strcspn_c3 (__const char *__s, int __reject1, int __reject2,
       int __reject3)
{
  register size_t __result = 0;
  while (__s[__result] != '\0' && __s[__result] != __reject1
  && __s[__result] != __reject2 && __s[__result] != __reject3)
    ++__result;
  return __result;
}
# 1045 "/usr/include/bits/string2.h" 3 4
extern __inline size_t __strspn_c1 (__const char *__s, int __accept);
extern __inline size_t
__strspn_c1 (__const char *__s, int __accept)
{
  register size_t __result = 0;

  while (__s[__result] == __accept)
    ++__result;
  return __result;
}

extern __inline size_t __strspn_c2 (__const char *__s, int __accept1,
        int __accept2);
extern __inline size_t
__strspn_c2 (__const char *__s, int __accept1, int __accept2)
{
  register size_t __result = 0;

  while (__s[__result] == __accept1 || __s[__result] == __accept2)
    ++__result;
  return __result;
}

extern __inline size_t __strspn_c3 (__const char *__s, int __accept1,
        int __accept2, int __accept3);
extern __inline size_t
__strspn_c3 (__const char *__s, int __accept1, int __accept2, int __accept3)
{
  register size_t __result = 0;

  while (__s[__result] == __accept1 || __s[__result] == __accept2
  || __s[__result] == __accept3)
    ++__result;
  return __result;
}
# 1121 "/usr/include/bits/string2.h" 3 4
extern __inline char *__strpbrk_c2 (__const char *__s, int __accept1,
         int __accept2);
extern __inline char *
__strpbrk_c2 (__const char *__s, int __accept1, int __accept2)
{

  while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
    ++__s;
  return *__s == '\0' ? ((void *)0) : (char *) (size_t) __s;
}

extern __inline char *__strpbrk_c3 (__const char *__s, int __accept1,
         int __accept2, int __accept3);
extern __inline char *
__strpbrk_c3 (__const char *__s, int __accept1, int __accept2,
       int __accept3)
{

  while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
  && *__s != __accept3)
    ++__s;
  return *__s == '\0' ? ((void *)0) : (char *) (size_t) __s;
}
# 1172 "/usr/include/bits/string2.h" 3 4
extern __inline char *__strtok_r_1c (char *__s, char __sep, char **__nextp);
extern __inline char *
__strtok_r_1c (char *__s, char __sep, char **__nextp)
{
  char *__result;
  if (__s == ((void *)0))
    __s = *__nextp;
  while (*__s == __sep)
    ++__s;
  __result = ((void *)0);
  if (*__s != '\0')
    {
      __result = __s++;
      while (*__s != '\0')
 if (*__s++ == __sep)
   {
     __s[-1] = '\0';
     break;
   }
    }
  *__nextp = __s;
  return __result;
}
# 1204 "/usr/include/bits/string2.h" 3 4
extern char *__strsep_g (char **__stringp, __const char *__delim);
# 1222 "/usr/include/bits/string2.h" 3 4
extern __inline char *__strsep_1c (char **__s, char __reject);
extern __inline char *
__strsep_1c (char **__s, char __reject)
{
  register char *__retval = *__s;
  if (__retval != ((void *)0) && (*__s = (__extension__ (__builtin_constant_p
(__reject) && !__builtin_constant_p (__retval) && (__reject) == '\0' ? (char *)
__rawmemchr (__retval, __reject) : __builtin_strchr (__retval, __reject)))) !=
((void *)0))
    *(*__s)++ = '\0';
  return __retval;
}

extern __inline char *__strsep_2c (char **__s, char __reject1, char __reject2);
extern __inline char *
__strsep_2c (char **__s, char __reject1, char __reject2)
{
  register char *__retval = *__s;
  if (__retval != ((void *)0))
    {
      register char *__cp = __retval;
      while (1)
 {
   if (*__cp == '\0')
     {
       __cp = ((void *)0);
   break;
     }
   if (*__cp == __reject1 || *__cp == __reject2)
     {
       *__cp++ = '\0';
       break;
     }
   ++__cp;
 }
      *__s = __cp;
    }
  return __retval;
}

extern __inline char *__strsep_3c (char **__s, char __reject1, char __reject2,
       char __reject3);
extern __inline char *
__strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
{
  register char *__retval = *__s;
  if (__retval != ((void *)0))
    {
      register char *__cp = __retval;
      while (1)
 {
   if (*__cp == '\0')
     {
       __cp = ((void *)0);
   break;
     }
   if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
     {
       *__cp++ = '\0';
       break;
     }
   ++__cp;
 }
      *__s = __cp;
    }
  return __retval;
}
# 1298 "/usr/include/bits/string2.h" 3 4
# 1 "/usr/include/stdlib.h" 1 3 4
# 33 "/usr/include/stdlib.h" 3 4
# 1 "/usr/lib/gcc/i586-redhat-linux/4.4.0/include/stddef.h" 1 3 4
# 34 "/usr/include/stdlib.h" 2 3 4


# 469 "/usr/include/stdlib.h" 3 4


extern void *malloc (size_t __size) __attribute__ ((__nothrow__)) __attribute__
((__malloc__)) ;

extern void *calloc (size_t __nmemb, size_t __size)
     __attribute__ ((__nothrow__)) __attribute__ ((__malloc__)) ;

# 912 "/usr/include/stdlib.h" 3 4

# 1299 "/usr/include/bits/string2.h" 2 3 4




extern char *__strdup (__const char *__string) __attribute__ ((__nothrow__))
__attribute__ ((__malloc__));
# 1322 "/usr/include/bits/string2.h" 3 4
extern char *__strndup (__const char *__string, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__malloc__));
# 636 "/usr/include/string.h" 2 3 4
# 644 "/usr/include/string.h" 3 4

# 52 "bug11.c" 2



static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
        int oldbit;

        __asm__ __volatile__(
                "btrl %2,%1\n\tsbbl %0,%0"
                :"=r" (oldbit),"=m" ((*(volatile long *) addr))
                :"Ir" (nr) : "memory");
        return oldbit;
}
static __inline__ void set_bit(int nr, volatile void * addr)
{
        __asm__ __volatile__(
                "btsl %1,%0"
                :"=m" ((*(volatile long *) addr))
                :"Ir" (nr));
}



void good11( int how, unsigned numpoints, unsigned short *points,
              unsigned short hix, unsigned short hiy,
              unsigned short orgx, unsigned short orgy )
{
  unsigned short xx, yy, penbit;

  for ( ; numpoints; numpoints--, points += 2 ) {
    xx = points[0];
    penbit = xx & 0x8000; xx &= 0x7fff;
    yy = points[1];
    if ( xx > hix ) {
      if ( how == 0 ) xx = hix;
      else if ( how == 1 ) xx = 0;
      else do { xx -= hix; } while ( xx > hix );
    }
    xx += orgx;
    if ( yy > hiy ) {
      if ( how == 0 ) yy = hiy;
      else if ( how == 1 ) yy = 0;
      else do { yy -= hiy; } while ( yy > hiy );
    }
    yy += orgy;
    points[0] = xx | penbit; points[1] = yy;
  }
}
# 128 "bug11.c"
void bad11( int how, unsigned numpoints, unsigned short *points,
            unsigned short hix, unsigned short hiy,
            unsigned short orgx, unsigned short orgy )
{
  unsigned short xx, yy;
  int penbit;

  for ( ; numpoints; numpoints--, points += 2 ) {
    xx = points[0]; penbit = test_and_clear_bit( 15, (void *)&xx );
    yy = points[1];
    if ( xx > hix ) {
      if ( how == 0 ) xx = hix;
      else if ( how == 1 ) xx = 0;
      else do { xx -= hix; } while ( xx > hix );
    }
    xx += orgx;
    if ( yy > hiy ) {
      if ( how == 0 ) yy = hiy;
      else if ( how == 1 ) yy = 0;
      else do { yy -= hiy; } while ( yy > hiy );
    }
    yy += orgy;
    if ( penbit ) set_bit( 15, (void *)&xx );
    points[0] = xx; points[1] = yy;
  }
}

unsigned short xy[20] = { 0,0, 0x8010,0x10, 0x100,0x100, 0x8200,0x200,
0x300,0x300, 0x8400,0x400, 0x500,0x500, 0x8600,0x600, 0x700,0x700, 0x8800,0x800
};
unsigned short xy_good[20], xy_bad[20];

int main( void )
{
  memcpy( xy_good, xy, sizeof(xy_good) );
  good11( 0, 10, xy_good, 0x550, 0x550, 0, 0 );
  memcpy( xy_bad, xy, sizeof(xy_good) );
  bad11( 0, 10, xy_bad, 0x550, 0x550, 0, 0 );
# 176 "bug11.c"
  memcpy( xy_good, xy, sizeof(xy_good) );
  good11( 0, 10, xy_good, 0x550, 0x550, 0x111, 0x222 );
  memcpy( xy_bad, xy, sizeof(xy_good) );
  bad11( 0, 10, xy_bad, 0x550, 0x550, 0x111, 0x222 );
# 191 "bug11.c"
  return 0;
}

-----------------------bug11.x (stdout and stderr from gcc -v -save-temps....)
Using built-in specs.
Target: i586-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
--disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
--with-ppl --with-cloog --with-tune=generic --with-arch=i586
--build=i586-redhat-linux
Thread model: posix
gcc version 4.4.0 20090506 (Red Hat 4.4.0-4) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-o' 'bug11'
'-mtune=generic' '-march=i586'
 /usr/libexec/gcc/i586-redhat-linux/4.4.0/cc1 -E -quiet -v bug11.c
-mtune=generic -march=i586 -Wall -O -fpch-preprocess -o bug11.i
ignoring nonexistent directory
"/usr/lib/gcc/i586-redhat-linux/4.4.0/include-fixed"
ignoring nonexistent directory
"/usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../i586-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i586-redhat-linux/4.4.0/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-o' 'bug11'
'-mtune=generic' '-march=i586'
 /usr/libexec/gcc/i586-redhat-linux/4.4.0/cc1 -fpreprocessed bug11.i -quiet
-dumpbase bug11.c -mtune=generic -march=i586 -auxbase bug11 -O -Wall -version
-o bug11.s
GNU C (GCC) version 4.4.0 20090506 (Red Hat 4.4.0-4) (i586-redhat-linux)
        compiled by GNU C version 4.4.0 20090506 (Red Hat 4.4.0-4), GMP version
4.2.4, MPFR version 2.4.1.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 040f83d86f09a0c9faa7c6a16b75ce72
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-o' 'bug11'
'-mtune=generic' '-march=i586'
 as -V -Qy -o bug11.o bug11.s
GNU assembler version 2.19.51.0.2 (i586-redhat-linux) using BFD version version
2.19.51.0.2-17.fc11 20090204
COMPILER_PATH=/usr/libexec/gcc/i586-redhat-linux/4.4.0/:/usr/libexec/gcc/i586-redhat-linux/4.4.0/:/usr/libexec/gcc/i586-redhat-linux/:/usr/lib/gcc/i586-redhat-linux/4.4.0/:/usr/lib/gcc/i586-redhat-linux/:/usr/libexec/gcc/i586-redhat-linux/4.4.0/:/usr/libexec/gcc/i586-redhat-linux/:/usr/lib/gcc/i586-redhat-linux/4.4.0/:/usr/lib/gcc/i586-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/i586-redhat-linux/4.4.0/:/usr/lib/gcc/i586-redhat-linux/4.4.0/:/usr/lib/gcc/i586-redhat-linux/4.4.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O' '-Wall' '-o' 'bug11'
'-mtune=generic' '-march=i586'
 /usr/libexec/gcc/i586-redhat-linux/4.4.0/collect2 --eh-frame-hdr --build-id -m
elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 -o bug11
/usr/lib/gcc/i586-redhat-linux/4.4.0/../../../crt1.o
/usr/lib/gcc/i586-redhat-linux/4.4.0/../../../crti.o
/usr/lib/gcc/i586-redhat-linux/4.4.0/crtbegin.o
-L/usr/lib/gcc/i586-redhat-linux/4.4.0 -L/usr/lib/gcc/i586-redhat-linux/4.4.0
-L/usr/lib/gcc/i586-redhat-linux/4.4.0/../../.. bug11.o -lgcc --as-needed
-lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/i586-redhat-linux/4.4.0/crtend.o
/usr/lib/gcc/i586-redhat-linux/4.4.0/../../../crtn.o


-- 
           Summary: incorrect code when using ..._bit macros from
                    asm/bitops.h in a loop in userspace program
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mcconnau at biochem dot wustl dot edu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40988

Reply via email to