(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
i386/
sse4_2-crc32.h
       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  
      10  static void
      11  shift_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  
      23  static void
      24  do_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  
      31  static unsigned int
      32  calc_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  
      66  static void 
      67  reverse_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  
      87  static void 
      88  shift_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  
      98  static void 
      99  xor_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  
     108  static DST_T
     109  compute_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  
     143  static void
     144  sse4_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  }