/* 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