/* (272,190)符合の訂正プログラム 1999-2002 (c) Hiroki Mori このプログラムでは82ビットのシンドロームレジスタを24ビット・28ビット・ 30ビットに分割して処理しています。 1999-03-28 first edition 2002-04-28 Optimization and add MMX code */ #define NOERROR 0 #define USEREG 1 #define NOOPTIMIZ 0 #define USEMMX 1 #define NOJMP 0 #define TESTCOUNT (4*2*30*10) unsigned long r[4]__attribute__((aligned(8))); unsigned char val0[8]__attribute__((aligned(8))) = {0x08, 0x02, 0xa2, 0x00, 0x00, 0x8a, 0x80, 0x08}; unsigned char val1[8]__attribute__((aligned(8))) = {0x08, 0x60, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00}; /* r0 ^= 0x00a20208; r1 ^= 0x08808a00; r2 ^= 0x01846008; */ unsigned char vbipacket[] = { 0x55, 0x55, 0xa7, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd3, 0x44, 0x60, 0xee, 0x1f, 0x6f, 0x52, 0xb6, 0xc6, 0xa3}; #if USEMMX void shift82(int bit) { unsigned long next; next = (r[2] & 0x20000000) ? 1 : 0; bit = next ^ bit; #if !(NOJMP) if(next) { #endif asm( /* mm7 = 1 */ /* "pcmpeqd %%mm7,%%mm7\n" "psrlq $63, %%mm7\n"*/ #if NOJMP "pxor %%mm0,%%mm0\n" "movd (%5),%%mm6\n" "punpckldq %%mm6,%%mm6\n" "pcmpgtd %%mm0, %%mm6\n" #endif "movq (%0),%%mm0\n" /* "movq (%1),%%mm1\n"*/ "movq %%mm5,%%mm1\n" #if NOJMP "pand %%mm6,%%mm1\n" #endif "pxor %%mm1,%%mm0\n" /* r[0] << 1 & r[1] << 1 */ "pslld $1,%%mm0\n" /* r[1] |= ((r[0] >> 24) & 1) */ "movq %%mm0,%%mm4\n" "psrlq $24,%%mm4\n" "pand %%mm7,%%mm4\n" "psllq $32,%%mm4\n" "por %%mm4,%%mm0\n" /* r[0] |= bit */ "movd (%4),%%mm4\n" "por %%mm4,%%mm0\n" "movq %%mm0,(%0)\n" /* r2 */ "movq (%2),%%mm2\n" /* "movq (%3),%%mm3\n"*/ #if NOJMP /* "pand %%mm6,%%mm3\n"*/ "pand %%mm3,%%mm6\n" "pxor %%mm6,%%mm2\n" #else "pxor %%mm3,%%mm2\n" #endif /* r[2] << 1 */ "pslld $1,%%mm2\n" /* r[2] != ((r[1] >> 28) & 1) */ "psrlq $60, %%mm0\n" "pand %%mm7,%%mm0\n" "por %%mm0,%%mm2\n" "movq %%mm2,(%2)\n" /* "emms\n"*/ : :"r"(&r[0]), "r"(val0), "r"(&r[2]), "r"(val1), "r"(&bit), "r"(&next) ); #if !(NOJMP) } else { asm( "movq (%0),%%mm0\n" "movq (%1),%%mm1\n" /* r[0] << 1 & r[1] << 1 */ "pslld $1,%%mm0\n" /* r[2] << 1 */ "pslld $1,%%mm1\n" /* mm7 = 1 */ /* "pcmpeqd %%mm7,%%mm7\n" "psrlq $63, %%mm7\n"*/ /* r[1] |= ((r[0] >> 24) & 1) */ "movq %%mm0,%%mm4\n" "psrlq $24,%%mm4\n" "pand %%mm7,%%mm4\n" "psllq $32,%%mm4\n" "por %%mm4,%%mm0\n" /*r[0] |= bit*/ "movd (%2),%%mm4\n" "por %%mm4,%%mm0\n" /* r[0-1] = mm0 */ "movq %%mm0,(%0)\n" /* r[2] |= ((r[1] >> 28) & 1) */ "psrlq $60, %%mm0\n" "pand %%mm7,%%mm0\n" "por %%mm0,%%mm1\n" /* r[2] = mm1 */ "movq %%mm1,(%1)\n" /* "emms\n"*/ : :"r"(&r[0]), "r"(&r[2]), "r"(&bit) ); } #endif } #else void shift82(int bit) { unsigned long next; next = ((r[2] >> 29) & 1); if(next) { r[0] ^= 0x00a20208; r[1] ^= 0x08808a00; r[2] ^= 0x01846008; } r[0] <<= 1; r[1] <<= 1; r[1] |= ((r[0] >> 24) & 1); r[2] <<= 1; r[2] |= ((r[1] >> 28) & 1); r[0] |= (next ^ bit); } #endif #if NOOPTIMIZ int getbit(int bit) { if(bit >= 52) return((r[2] >> (bit - 52)) & 1); else if(bit >= 24) return((r[1] >> (bit - 24)) & 1); else return((r[0] >> bit) & 1); } #define GETBIT2(NUM) getbit(NUM) #define GETBIT1(NUM) getbit(NUM) #define GETBIT0(NUM) getbit(NUM) #else #define GETBIT2(NUM) ((r[2] >> (NUM - 52)) & 1) #define GETBIT1(NUM) ((r[1] >> (NUM - 24)) & 1) #define GETBIT0(NUM) ((r[0] >> NUM) & 1) #endif int majority(int border) { #if USEREG register int sum; #else int sum; #endif sum = GETBIT2(71) ^ GETBIT2(76); sum += GETBIT0(17); sum += GETBIT0(5) ^ GETBIT0(23); sum += GETBIT0(21) ^ GETBIT1(27) ^ GETBIT1(45); sum += GETBIT0(3) ^ GETBIT1(25) ^ GETBIT1(31) ^ GETBIT1(49); sum += GETBIT0(16) ^ GETBIT0(20) ^ GETBIT1(42) ^ GETBIT1(48) ^ GETBIT2(66); sum += GETBIT1(35) ^ GETBIT2(52) ^ GETBIT2(56) ^ GETBIT2(78); sum += GETBIT0(8) ^ GETBIT1(44) ^ GETBIT2(61) ^ GETBIT2(65); sum += GETBIT0(2) ^ GETBIT0(11) ^ GETBIT1(47) ^ GETBIT2(64) ^ GETBIT2(68); sum += GETBIT0(10) ^ GETBIT0(13) ^ GETBIT0(22) ^ GETBIT2(58) ^ GETBIT2(75) ^ GETBIT2(79); sum += GETBIT0(1) ^ GETBIT0(12) ^ GETBIT0(15) ^ GETBIT1(24) ^ GETBIT2(60) ^ GETBIT2(77) ^ GETBIT2(81); sum += GETBIT1(30) ^ GETBIT1(32) ^ GETBIT1(43) ^ GETBIT1(46) ^ GETBIT2(55); sum += GETBIT0(6) ^ GETBIT1(37) ^ GETBIT1(39) ^ GETBIT1(50) ^ GETBIT2(53) ^ GETBIT2(62); sum += GETBIT0(0) ^ GETBIT0(7) ^ GETBIT1(38) ^ GETBIT1(40) ^ GETBIT1(51) ^ GETBIT2(54) ^ GETBIT2(63); sum += GETBIT0(18) ^ GETBIT0(19) ^ GETBIT1(26) ^ GETBIT2(57) ^ GETBIT2(59) ^ GETBIT2(70) ^ GETBIT2(73); sum += GETBIT0(9) ^ GETBIT1(28) ^ GETBIT1(29) ^ GETBIT1(36) ^ GETBIT2(67) ^ GETBIT2(69) ^ GETBIT2(80); sum += GETBIT0(4) ^ GETBIT0(14) ^ GETBIT1(33) ^ GETBIT1(34) ^ GETBIT1(41) ^ GETBIT1(41) ^ GETBIT2(72) ^ GETBIT2(74); return sum >= border ? 1 : 0; } int correct272(unsigned char *data) { int i, j, k; unsigned char *ptr, byte, cbyte; int majo, bit; r[0] = r[1] = r[2] = 0; j = 0; ptr = data + 3; #if USEMMX asm ( "pcmpeqd %%mm7,%%mm7\n" "psrlq $63, %%mm7\n" "movq (%0),%%mm5\n" "movq (%1),%%mm3\n" : :"r"(val0), "r"(val1) ); #endif while(j < 272) { byte = *ptr++; for(i = 0; i < 8; ++i) { shift82((byte >> i) & 1); ++j; } } if((r[0] & 0xffffff) == 0 && (r[1] & 0xfffffff) == 0 && (r[2] & 0x3fffffff) == 0) goto success; for(k = 14; k >= 9; --k) { shift82(0); j = 0; ptr = data + 3; while(j < 272) { byte = *ptr; cbyte = 0; for(i = 0; i < 8; ++i) { majo = majority(k); bit = ((byte >> i) & 1) ^ majo; shift82(majo); cbyte |= (bit << i); ++j; } *ptr = cbyte; ++ptr; } if((r[0] & 0xffffff) == 0 && (r[1] & 0xfffffff) == 0 && (r[2] & 0x3fffffff) == 0) goto success; } return 0; success: return 1; } int main(int argc, char **argv) { int i; unsigned char *tmpbuf; tmpbuf = (unsigned char *)malloc(sizeof(vbipacket)); if(argc == 2 && !strcmp("-t", argv[1])) { memcpy(tmpbuf, vbipacket, sizeof(vbipacket)); #if !(NOERROR) // error data tmpbuf[5] = 0x01; tmpbuf[8] = 0x0f; tmpbuf[10] = 0x0f; tmpbuf[17] = 0x01; tmpbuf[20] = 0x01; tmpbuf[31] = 0x3f; #endif for(i = 0;i < sizeof(vbipacket); ++i) { printf("%02x ", tmpbuf[i]); if(i % 16 == 15) printf("\n"); } printf("\n"); printf("test %s\n",correct272(tmpbuf) ? "OK" : "NG"); for(i = 0;i < sizeof(vbipacket); ++i) { printf("%02x ", tmpbuf[i]); if(i % 16 == 15) printf("\n"); } printf("\n"); } else { for(i = 0;i < TESTCOUNT; ++i) { memcpy(tmpbuf, vbipacket, sizeof(vbipacket)); // error data #if !(NOERROR) tmpbuf[5] = 0x01; tmpbuf[8] = 0x0f; tmpbuf[10] = 0x0f; tmpbuf[17] = 0x01; tmpbuf[20] = 0x01; tmpbuf[31] = 0x3f; #endif if(!correct272(tmpbuf)) { printf("Error occur\n"); break; } } } return 1; }