+
+ partial = 0;
+ if ((uintptr_t)data & 1) {
+ /* Align on word boundary */
+ started_on_odd = !started_on_odd;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ partial = *data << 8;
+#else /* BYTE_ORDER != LITTLE_ENDIAN */
+ partial = *data;
+#endif /* BYTE_ORDER != LITTLE_ENDIAN */
+ ++data;
+ --mlen;
+ }
+ needs_swap = started_on_odd;
+ while (mlen >= 32) {
+ __builtin_prefetch(data + 32);
+ partial += *(uint16_t *)(void *)data;
+ partial += *(uint16_t *)(void *)(data + 2);
+ partial += *(uint16_t *)(void *)(data + 4);
+ partial += *(uint16_t *)(void *)(data + 6);
+ partial += *(uint16_t *)(void *)(data + 8);
+ partial += *(uint16_t *)(void *)(data + 10);
+ partial += *(uint16_t *)(void *)(data + 12);
+ partial += *(uint16_t *)(void *)(data + 14);
+ partial += *(uint16_t *)(void *)(data + 16);
+ partial += *(uint16_t *)(void *)(data + 18);
+ partial += *(uint16_t *)(void *)(data + 20);
+ partial += *(uint16_t *)(void *)(data + 22);
+ partial += *(uint16_t *)(void *)(data + 24);
+ partial += *(uint16_t *)(void *)(data + 26);
+ partial += *(uint16_t *)(void *)(data + 28);
+ partial += *(uint16_t *)(void *)(data + 30);
+ data += 32;
+ mlen -= 32;
+ if (__improbable(partial & 0xc0000000)) {
+ if (needs_swap)
+ partial = (partial << 8) +
+ (partial >> 24);
+ sum += (partial >> 16);
+ sum += (partial & 0xffff);
+ partial = 0;
+ }
+ }
+ if (mlen & 16) {
+ partial += *(uint16_t *)(void *)data;
+ partial += *(uint16_t *)(void *)(data + 2);
+ partial += *(uint16_t *)(void *)(data + 4);
+ partial += *(uint16_t *)(void *)(data + 6);
+ partial += *(uint16_t *)(void *)(data + 8);
+ partial += *(uint16_t *)(void *)(data + 10);
+ partial += *(uint16_t *)(void *)(data + 12);
+ partial += *(uint16_t *)(void *)(data + 14);
+ data += 16;
+ mlen -= 16;