egcs-1.1.2 breaks ping(1) on i386
Jeffrey A Law
law@upchuck.cygnus.com
Mon May 24 14:57:00 GMT 1999
In message <199904120025.UAA01830@sleipnir.valparaiso.cl>you write:
> ------- =_aaaaaaaaaa0
> Content-Type: text/plain; charset="us-ascii"
> Content-ID: <1823.923876521.1@sleipnir.valparaiso.cl>
>
> The ping source from the widely deployed netkit-0.10 breaks when compiled
> on ia32 with egcs-1.1.2. A testcase follows, with annotated .s file (buggy
> asm pointed out by "Petr Vandrovec Ing. VTEI" <VANDROVE@vc.cvut.cz>).
>
> ------- =_aaaaaaaaaa0
> Content-Type: text/plain; name="tst.c"; charset="us-ascii"
> Content-ID: <1823.923876521.2@sleipnir.valparaiso.cl>
> Content-Description: Checksum routine from ping.c in netkit-0.10 source (ed
> ited)
>
> /*
> * in_cksum --
> * Checksum routine for Internet Protocol family headers (C Version)
> */
> static int
> in_cksum(unsigned short *addr, int len)
> {
> register int nleft = len;
> register unsigned short *w = addr;
> register int sum = 0;
> unsigned short answer = 0;
>
> /*
> * Our algorithm is simple, using a 32 bit accumulator (sum), we add
> * sequential 16 bit words to it, and at the end, fold back all the
> * carry bits from the top 16 bits into the lower 16 bits.
> */
> while (nleft > 1) {
> sum += *w++;
> nleft -= 2;
> }
>
> /* mop up an odd byte, if necessary */
> if (nleft == 1) {
> *(unsigned char *)(&answer) = *(unsigned char *)w ;
> sum += answer;
> }
>
> /* add back carry outs from top 16 bits to low 16 bits */
> sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
> sum += (sum >> 16); /* add carry */
> answer = ~sum; /* truncate to 16 bits */
> return(answer);
> }
I just checked this with the current sources and I'm pretty sure we generate
correct code with the gcc-2.95 CVS sources.
Jeff
More information about the Gcc-bugs
mailing list