-rw-r--r-- 1998 libsecded-20220828/correct.c raw
#include <inttypes.h> #include "secded.h" #define BOTTOM 7 #define TWOBOTTOM 128 unsigned int secded_correct(void *x_arg,long long n,const void *parity_arg) { uint8_t *x = (uint8_t *) x_arg; const uint8_t *parity = (const uint8_t *) parity_arg; long long bits = 0; long long twobits = 1; long long bit,twobit; uint8_t flipbottom[TWOBOTTOM]; long long ntop = n>>BOTTOM; uint8_t flip,fliptop,overall,anyp,borrow,nmask,pmask,sec,ded; if (n <= 0) return 0; while (twobits < n) { ++bits; twobits += twobits; } overall = parity[bits]; anyp = 0; borrow = 0; for (bit = 0;bit < bits;++bit) { nmask = -(1&(n>>bit)); pmask = parity[bit]; anyp |= pmask; borrow = (nmask&borrow&pmask)|((nmask|borrow)&~pmask); } nmask = -(1&(n>>bits)); borrow |= nmask; sec = borrow&overall; ded = (anyp&~overall)|(overall&~borrow); for (long long j = 0;j < TWOBOTTOM;++j) { flip = 0xff; bit = 0; twobit = 1; while (bit < bits && bit < BOTTOM) { if (j & twobit) flip &= parity[bit]; else flip &= ~parity[bit]; ++bit; twobit += twobit; } flipbottom[j] = flip; } for (long long k = 0;k < ntop<<BOTTOM;k += TWOBOTTOM) { fliptop = overall; bit = BOTTOM; twobit = TWOBOTTOM; while (bit < bits) { if (k & twobit) fliptop &= parity[bit]; else fliptop &= ~parity[bit]; ++bit; twobit += twobit; } for (long long j = 0;j < TWOBOTTOM;++j) x[k+j] ^= fliptop&flipbottom[j]; } { long long k = ntop<<BOTTOM; fliptop = overall; bit = BOTTOM; twobit = TWOBOTTOM; while (bit < bits) { if (k & twobit) fliptop &= parity[bit]; else fliptop &= ~parity[bit]; ++bit; twobit += twobit; } for (long long j = 0;j < TWOBOTTOM;++j) if (k+j < n) x[k+j] ^= fliptop&flipbottom[j]; } return ((unsigned int) sec) | (((unsigned int) ded) << 8); }