1#include "sse4_2-check.h" 2 3#include <nmmintrin.h> 4#include <string.h> 5 6#define POLYNOMIAL 0x11EDC6F41LL 7 8#define MAX_BUF 16 9 10static void 11shift_mem_by1 (unsigned char* buf, int len) 12{ 13 int i; 14 15 for (i = len - 1; i >= 0; i--) 16 { 17 buf[i] = buf[i] << 1; 18 if (i > 0 && (buf[i-1] & 0x80)) 19 buf[i] |= 1; 20 } 21} 22 23static void 24do_div (unsigned char* buf, unsigned char* div) 25{ 26 int i; 27 for (i = 0; i < 5; i++) 28 buf[i] ^= div[i]; 29} 30 31static unsigned int 32calc_rem (unsigned char* buf, int len) 33{ 34 union 35 { 36 unsigned long long ll; 37 unsigned char c[8]; 38 } divisor; 39 union 40 { 41 unsigned int i; 42 unsigned char c[4]; 43 } ret; 44 unsigned char *div_buf; 45 unsigned char divident[MAX_BUF]; 46 int disp = len / 8; 47 int i; 48 49 divisor.ll = POLYNOMIAL << 7LL; 50 51 memcpy (divident, buf, disp); 52 53 div_buf = divident + disp - 5; 54 55 for (i = 0; i < len - 32; i++) 56 { 57 if ((div_buf[4] & 0x80)) 58 do_div (div_buf, divisor.c); 59 shift_mem_by1 (divident, disp); 60 } 61 62 memcpy (ret.c, div_buf + 1, sizeof (ret)); 63 return ret.i; 64} 65 66static void 67reverse_bits (unsigned char *src, int len) 68{ 69 unsigned char buf[MAX_BUF]; 70 unsigned char *tmp = buf + len - 1; 71 unsigned char ch; 72 int i, j; 73 74 for (i = 0; i < len; i++) 75 { 76 ch = 0; 77 for (j = 0; j < 8; j++) 78 if ((src[i] & (1 << j))) 79 ch |= 1 << (7 - j); 80 *tmp-- = ch; 81 } 82 83 for (i = 0; i < len; i++) 84 src[i] = buf[i]; 85} 86 87static void 88shift_mem ( unsigned char *src, unsigned char *dst, int len, int shft) 89{ 90 int disp = shft / 8; 91 int i; 92 93 memset (dst, 0, len + disp); 94 for (i = 0; i < len; i++) 95 dst[i + disp] = src[i]; 96} 97 98static void 99xor_mem (unsigned char *src, unsigned char *dst, int len) 100{ 101 int disp = len / 8; 102 int i; 103 104 for (i = 0; i < disp; i++) 105 dst[i] ^= src[i]; 106} 107 108static DST_T 109compute_crc32 (DST_T crc, SRC_T inp) 110{ 111 unsigned char crcbuf[sizeof (DST_T)]; 112 unsigned char inbuf[sizeof (SRC_T)]; 113 unsigned char tmp1[MAX_BUF], tmp2[MAX_BUF]; 114 int crc_sh, xor_sz; 115 union 116 { 117 unsigned int i; 118 unsigned char c[4]; 119 } ret; 120 121 crc_sh = sizeof (SRC_T) * 8; 122 xor_sz = 32 + crc_sh; 123 memcpy (crcbuf, &crc, sizeof (DST_T)); 124 memcpy (inbuf, &inp, sizeof (SRC_T)); 125 126 reverse_bits (crcbuf, 4); 127 reverse_bits (inbuf, sizeof (SRC_T)); 128 129 shift_mem (inbuf, tmp1, sizeof (SRC_T), 32); 130 shift_mem (crcbuf, tmp2, 4, crc_sh); 131 132 xor_mem (tmp1, tmp2, xor_sz); 133 134 ret.i = calc_rem (tmp2, xor_sz); 135 136 reverse_bits (ret.c, 4); 137 138 return (DST_T)ret.i; 139} 140 141#define NUM 1024 142 143static void 144sse4_2_test (void) 145{ 146 DST_T dst[NUM]; 147 SRC_T src[NUM]; 148 int i; 149 150 for (i = 0; i < NUM; i++) 151 { 152 dst[i] = rand (); 153 if (sizeof (DST_T) > 4) 154 dst[i] |= (DST_T)rand () << (DST_T)(sizeof (DST_T) * 4); 155 src[i] = rand (); 156 if (sizeof (SRC_T) > 4) 157 src[i] |= (SRC_T)rand () << (SRC_T)(sizeof (DST_T) * 4); 158 } 159 160 for (i = 0; i < NUM; i++) 161 if (CRC32 (dst[i], src[i]) != compute_crc32 (dst[i], src[i])) 162 abort (); 163} 164