Subject: i386: miscompilaton or bogus C source?
To: None <tech-toolchain@netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-toolchain
Date: 06/08/1999 17:45:28
The following Intenret checksum code fragment (which is from Craig
Partrdige, tuned for portability, rather than speed) worked fine on an
i386 with gcc 2.7.2.2+myc1.

With our egcs-1.1.1, it produces incorrect results. If I #define'ing
DEBUG (turning on the debugging fprintf()) i get correct results
again.

Is this a bug in EGCS, or is the C code tripping over ANSI
end-of-array rules?

-------

#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include "xsum.h"

/**************************************************************************/
/* do the checksum                                                        */
/**************************************************************************/

u_long xsum(const u_char *buf,const int len)
{
    register int slen;
    register u_short *sp;
    register u_long sum;
    int extra;

    slen = len/2;
    extra = len & 0x1;
    sum = 0;

    sp=(u_short *)buf;

    for(; slen > 16; slen -= 16)
    {
	sum += *sp++;
	sum += *sp++;
	sum += *sp++;
	sum += *sp++;

	sum += *sp++;
	sum += *sp++;
	sum += *sp++;
	sum += *sp++;

	sum += *sp++;
	sum += *sp++;
	sum += *sp++;
	sum += *sp++;

	sum += *sp++;
	sum += *sp++;
	sum += *sp++;
	sum += *sp++;

	sum = (sum & 0xFFFF) + ((sum >> 16) & 0xFFFF);
    }

    /* do remainder */
    for(; slen > 0; slen--)
	sum += *sp++;

    if (extra)
    {
	u_short rem;
#if defined(DEBUG)
  fprintf(stderr, "!\n");
#endif

	rem = 0;
	*(char *)&rem = buf[len-1];
	sum += rem;
    }

    while (sum > 0xFFFF)
	sum = (sum & 0xFFFF) + ((sum >> 16) & 0xFFFF);

    sum = (u_short) sum;
    return(htons(sum));
}

#if 0

/**************************************************************************/
/*                                                                        */
/**************************************************************************/

u_short xsfold(u_long sum)
{
    do
    {
	sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF);
    }
    while (sum > 0xFFFF);
    return((u_short) sum);
}
#endif