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