/*********************************************************************** ** ** fletcher4.c ** ** Copyright (C) 2024 Herbert Poetzl ** ** gcc -Wall -O3 -march=armv8-a+crc -o fletcher4 fletcher4.c ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2 as ** published by the Free Software Foundation. ** ***********************************************************************/ #include #include #include #include #include uint64_t fletcher4(const uint8_t *data, size_t len) { uint32x4_t vzero = (uint32x4_t){0, 0, 0, 0}; register uint32x4_t v0, v1, v2, v3, v4; v0 = v1 = v2 = v3 = v4 = vzero; len >>= 4; while (len--) { v0 = vld1q_u32((uint32_t *)(data)); v1 = vaddq_u32(v1, v0); v2 = vaddq_u32(v2, v1); v3 = vaddq_u32(v3, v2); v4 = vaddq_u32(v4, v3); data += 16; } uint32_t a, b, c, d; a = 1*vgetq_lane_u32(v1, 0) + 1*vgetq_lane_u32(v1, 1) + 1*vgetq_lane_u32(v1, 2) + 1*vgetq_lane_u32(v1, 3); b = 4*vgetq_lane_u32(v2, 0) + 4*vgetq_lane_u32(v2, 1) + 4*vgetq_lane_u32(v2, 2) + 4*vgetq_lane_u32(v2, 3) - 1*vgetq_lane_u32(v1, 1) - 2*vgetq_lane_u32(v1, 2) - 3*vgetq_lane_u32(v1, 3); c = 16*vgetq_lane_u32(v3, 0) + 16*vgetq_lane_u32(v3, 1) + 16*vgetq_lane_u32(v3, 2) + 16*vgetq_lane_u32(v3, 3) - 6*vgetq_lane_u32(v2, 0) - 10*vgetq_lane_u32(v2, 1) - 14*vgetq_lane_u32(v2, 2) - 18*vgetq_lane_u32(v2, 3) + 1*vgetq_lane_u32(v1, 2) + 3*vgetq_lane_u32(v1, 3); d = 64*vgetq_lane_u32(v4, 0) + 64*vgetq_lane_u32(v4, 1) + 64*vgetq_lane_u32(v4, 2) + 64*vgetq_lane_u32(v4, 3) - 48*vgetq_lane_u32(v3, 0) - 64*vgetq_lane_u32(v3, 1) - 80*vgetq_lane_u32(v3, 2) - 96*vgetq_lane_u32(v3, 3) + 4*vgetq_lane_u32(v2, 0) + 10*vgetq_lane_u32(v2, 1) + 20*vgetq_lane_u32(v2, 2) + 34*vgetq_lane_u32(v2, 3) - 1*vgetq_lane_u32(v1, 3); uint64_t result = 0; result = a ^ c; result <<= 32; result ^= b ^ d; return result; } int main(int argc, char* argv[]) { size_t len = 256; char *endptr; if (argc > 1) len = strtoull(argv[1], &endptr, 10); uint8_t *buf = malloc(len); if (!buf) exit(1); size_t cnt = 0; do { cnt = fread(buf, 1, len, stdin); if (cnt != len) break; uint64_t fl4 = fletcher4(buf, len); printf("%016lX\n", fl4); } while (cnt == len); exit(0); }