{
const uint16_t* sp = buf;
- if (len > 1 )
+ // if pointer is 16 bit aligned calculate checksum in tight loop...
+ // gcc 5.4 -O3 generates unaligned quadword instructions that crash; fixed in gcc 8.0.1
+ if ( !( reinterpret_cast<std::uintptr_t>(sp) & 0x01 ) )
+ {
+ while ( len > 1 )
+ {
+ cksum += *sp++;
+ len -= 2;
+ }
+ // if len was odd, sum in the last byte...
+ if ( len )
+ cksum += (uint16_t) *(const uint8_t *)sp;
+ }
+ else if ( len > 1 )
{
std::size_t sn = ((len / 2) & 0xF); // == len/2 % 16
std::size_t n = (((len / 2) + 15) / 16); // ceiling of (len / 2) / 16
cksum += sp[15];
sp += 16;
}
+ // if len is odd, sum in the last byte...
+ if ( len & 0x01)
+ cksum += (uint16_t) *(const uint8_t *)sp;
}
- if (len & 1)
- cksum += (*(const unsigned char*)sp);
-
cksum = (cksum >> 16) + (cksum & 0x0000ffff);
cksum += (cksum >> 16);