Home | History | Annotate | Download | only in C
      1 /* XzCrc64.c -- CRC64 calculation
      2 2011-06-28 : Igor Pavlov : Public domain */
      3 
      4 #include "Precomp.h"
      5 
      6 #include "XzCrc64.h"
      7 #include "CpuArch.h"
      8 
      9 #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
     10 
     11 #ifdef MY_CPU_LE
     12   #define CRC_NUM_TABLES 4
     13 #else
     14   #define CRC_NUM_TABLES 5
     15   #define CRC_UINT64_SWAP(v) \
     16   ((v >> 56) | \
     17   ((v >> 40) & ((UInt64)0xFF <<  8)) | \
     18   ((v >> 24) & ((UInt64)0xFF << 16)) | \
     19   ((v >>  8) & ((UInt64)0xFF << 24)) | \
     20   ((v <<  8) & ((UInt64)0xFF << 32)) | \
     21   ((v << 24) & ((UInt64)0xFF << 40)) | \
     22   ((v << 40) & ((UInt64)0xFF << 48)) | \
     23    (v << 56))
     24   UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
     25 #endif
     26 
     27 #ifndef MY_CPU_BE
     28   UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
     29 #endif
     30 
     31 typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
     32 
     33 static CRC_FUNC g_Crc64Update;
     34 UInt64 g_Crc64Table[256 * CRC_NUM_TABLES];
     35 
     36 UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
     37 {
     38   return g_Crc64Update(v, data, size, g_Crc64Table);
     39 }
     40 
     41 UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size)
     42 {
     43   return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL;
     44 }
     45 
     46 void MY_FAST_CALL Crc64GenerateTable()
     47 {
     48   UInt32 i;
     49   for (i = 0; i < 256; i++)
     50   {
     51     UInt64 r = i;
     52     unsigned j;
     53     for (j = 0; j < 8; j++)
     54       r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1));
     55     g_Crc64Table[i] = r;
     56   }
     57   for (; i < 256 * CRC_NUM_TABLES; i++)
     58   {
     59     UInt64 r = g_Crc64Table[i - 256];
     60     g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
     61   }
     62 
     63   #ifdef MY_CPU_LE
     64 
     65   g_Crc64Update = XzCrc64UpdateT4;
     66 
     67 
     68 
     69 
     70 
     71 
     72   #else
     73   {
     74     #ifndef MY_CPU_BE
     75     UInt32 k = 1;
     76     if (*(const Byte *)&k == 1)
     77       g_Crc64Update = XzCrc64UpdateT4;
     78     else
     79     #endif
     80     {
     81       for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
     82       {
     83         UInt64 x = g_Crc64Table[i - 256];
     84         g_Crc64Table[i] = CRC_UINT64_SWAP(x);
     85       }
     86       g_Crc64Update = XzCrc64UpdateT1_BeT4;
     87     }
     88   }
     89   #endif
     90 }
     91