plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

ptclbsum.c (1158B)


      1 #include	<u.h>
      2 #include	<libc.h>
      3 #include	<ip.h>
      4 
      5 static	short	endian	= 1;
      6 static	uchar*	aendian	= (uchar*)&endian;
      7 #define	LITTLE	*aendian
      8 
      9 ushort
     10 ptclbsum(uchar *addr, int len)
     11 {
     12 	ulong losum, hisum, mdsum, x;
     13 	ulong t1, t2;
     14 
     15 	losum = 0;
     16 	hisum = 0;
     17 	mdsum = 0;
     18 
     19 	x = 0;
     20 	if((ulong)addr & 1) {
     21 		if(len) {
     22 			hisum += addr[0];
     23 			len--;
     24 			addr++;
     25 		}
     26 		x = 1;
     27 	}
     28 	while(len >= 16) {
     29 		t1 = *(ushort*)(addr+0);
     30 		t2 = *(ushort*)(addr+2);	mdsum += t1;
     31 		t1 = *(ushort*)(addr+4);	mdsum += t2;
     32 		t2 = *(ushort*)(addr+6);	mdsum += t1;
     33 		t1 = *(ushort*)(addr+8);	mdsum += t2;
     34 		t2 = *(ushort*)(addr+10);	mdsum += t1;
     35 		t1 = *(ushort*)(addr+12);	mdsum += t2;
     36 		t2 = *(ushort*)(addr+14);	mdsum += t1;
     37 		mdsum += t2;
     38 		len -= 16;
     39 		addr += 16;
     40 	}
     41 	while(len >= 2) {
     42 		mdsum += *(ushort*)addr;
     43 		len -= 2;
     44 		addr += 2;
     45 	}
     46 	if(x) {
     47 		if(len)
     48 			losum += addr[0];
     49 		if(LITTLE)
     50 			losum += mdsum;
     51 		else
     52 			hisum += mdsum;
     53 	} else {
     54 		if(len)
     55 			hisum += addr[0];
     56 		if(LITTLE)
     57 			hisum += mdsum;
     58 		else
     59 			losum += mdsum;
     60 	}
     61 
     62 	losum += hisum >> 8;
     63 	losum += (hisum & 0xff) << 8;
     64 	while(hisum = losum>>16)
     65 		losum = hisum + (losum & 0xffff);
     66 
     67 	return losum & 0xffff;
     68 }