Path: utzoo!telly!ddsw1!lll-winken!killer!pollux!ti-csl!cs.utexas.edu!tut.cis.ohio-state.edu!MOOSE.CITA.UTORONTO.CA!trq From: trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) Newsgroups: gnu.gcc.bug Subject: bug in m68k gcc 1.32 Message-ID: <8901201214.AA03028@moose.cita.utoronto.ca> Date: 20 Jan 89 12:14:23 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 186 The following code generates incorrect assembly when compiled with the "-g -O -fforce-mem" options. This is gcc version 1.32 on a Sun 3/50 running SunOs 3.5. The problem is that the assignment on line 117 from the long to the short grabs the wrong half of the long. Tom Quinn Canadian Institute for Theoretical Astrophysics trq@moose.cita.utoronto.ca UUCP - decvax!utgpu!moose!trq BITNET - quinn@utorphys.bitnet ARPA - trq%moose.cita.toronto.edu@relay.cs.net The compile: gcc -S -g -v -O -fforce-mem -c XConnDis.c gcc version 1.32 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__OPTIMIZE__ -D__HAVE_68881__ -Dmc68020 XConnDis.c /tmp/cca15882.cpp GNU CPP version 1.32 /usr/local/lib/gcc-cc1 /tmp/cca15882.cpp -quiet -dumpbase XConnDis.c -fforce-mem -g -O -version -o XConnDis.s GNU C version 1.32 (68k, MIT syntax) compiled by GNU C version 1.32. The offending assembly: L20: .stabd 68,0,117 movew a0@(8),a6@(-272) # this should be a "movew a0(10),a6@(-272)" .stabd 68,0,120 The code: ------------------------------------------------------------------------ typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned long u_long; char *strcat(); int strcmp(); char *strcpy(); int strlen(); struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; }; struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char *h_addr; }; char *strncpy(); extern char *index(); extern int errno; struct sockaddr { u_short sa_family; char sa_data[14]; }; struct sockaddr_un { short sun_family; char sun_path[109]; }; void bcopy(); int _XConnectDisplay (display_name, expanded_name, prop_name, screen_num) char *display_name; char *expanded_name; char *prop_name; int *screen_num; { char displaybuf[256]; register char *display_ptr; register char *numbuf_ptr; char *screen_ptr; int display_num; struct sockaddr_in inaddr; unsigned long hostinetaddr; struct sockaddr_un unaddr; struct sockaddr *addr; struct hostent *host_ptr; int addrlen; extern char *getenv(); extern struct hostent *gethostbyname(); int fd; char numberbuf[16]; char *dot_ptr = 0 ; (void) strncpy(displaybuf, display_name, sizeof(displaybuf)); if ((display_ptr = index((displaybuf), (':')) ) == 0 ) return (-1); *(display_ptr++) = '\0'; if (*display_ptr == '\0') return(-1); screen_ptr = display_ptr; numbuf_ptr = numberbuf; while (*screen_ptr != '\0') { if (*screen_ptr == '.') { if (dot_ptr) { screen_ptr++; break; } dot_ptr = numbuf_ptr; *(screen_ptr++) = '\0'; *(numbuf_ptr++) = '.'; } else { *(numbuf_ptr++) = *(screen_ptr++); } } if (dot_ptr == 0 ) { dot_ptr = numbuf_ptr; *(numbuf_ptr++) = '.'; *(numbuf_ptr++) = '0'; } else { if (*(numbuf_ptr - 1) == '.') *(numbuf_ptr++) = '0'; } *numbuf_ptr = '\0'; *screen_num = atoi(dot_ptr + 1); strcpy (prop_name, screen_ptr); display_num = atoi(display_ptr); if (displaybuf[0] == '\0') ; { if ((displaybuf[0] == '\0') || (strcmp("unix", displaybuf) == 0)) { unaddr.sun_family = 1 ; (void) strcpy(unaddr.sun_path, "/tmp/.X11-unix/X" ); strcat(unaddr.sun_path, display_ptr); addr = (struct sockaddr *) &unaddr; addrlen = strlen(unaddr.sun_path) + 2; if ((fd = socket((int) addr->sa_family, 1 , 0)) < 0) return(-1); } else { hostinetaddr = inet_addr (displaybuf); if (hostinetaddr == -1) { if ((host_ptr = gethostbyname(displaybuf)) == 0 ) { errno = 22 ; return(-1); } if (host_ptr->h_addrtype != 2 ) { errno = 41 ; return(-1); } inaddr.sin_family = host_ptr->h_addrtype; bcopy((char *)host_ptr->h_addr, (char *)&inaddr.sin_addr, sizeof(inaddr.sin_addr)); } else { inaddr.sin_addr.S_un.S_addr = hostinetaddr; inaddr.sin_family = 2 ; } addr = (struct sockaddr *) &inaddr; addrlen = sizeof (struct sockaddr_in); inaddr.sin_port = display_num; inaddr.sin_port += 6000 ; inaddr.sin_port = (inaddr.sin_port) ; if ((fd = socket((int) addr->sa_family, 1 , 0)) < 0) return(-1); { int mi = 1; setsockopt (fd, 6 , 0x01 , &mi, sizeof (int)); } } if (connect(fd, addr, addrlen) == -1) { (void) close (fd); return(-1); } } (void) fcntl(fd, 4 , 00004 ); display_ptr = displaybuf-1; while (*(++display_ptr) != '\0') ; *(display_ptr++) = ':'; numbuf_ptr = numberbuf; while (*numbuf_ptr != '\0') *(display_ptr++) = *(numbuf_ptr++); if (prop_name[0] != '\0') { char *cp; *(display_ptr++) = '.'; for (cp = prop_name; *cp; cp++) *(display_ptr++) = *cp; } *display_ptr = '\0'; (void) strcpy(expanded_name, displaybuf); return(fd); }