Home | History | Annotate | Download | only in C
      1 /* 7zCrcOpt.c -- CRC32 calculation
      2 2017-04-03 : Igor Pavlov : Public domain */
      3 
      4 #include "Precomp.h"
      5 
      6 #include "CpuArch.h"
      7 
      8 #ifndef MY_CPU_BE
      9 
     10 #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
     11 
     12 UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
     13 {
     14   const Byte *p = (const Byte *)data;
     15   for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
     16     v = CRC_UPDATE_BYTE_2(v, *p);
     17   for (; size >= 4; size -= 4, p += 4)
     18   {
     19     v ^= *(const UInt32 *)p;
     20     v =
     21           (table + 0x300)[((v      ) & 0xFF)]
     22         ^ (table + 0x200)[((v >>  8) & 0xFF)]
     23         ^ (table + 0x100)[((v >> 16) & 0xFF)]
     24         ^ (table + 0x000)[((v >> 24))];
     25   }
     26   for (; size > 0; size--, p++)
     27     v = CRC_UPDATE_BYTE_2(v, *p);
     28   return v;
     29 }
     30 
     31 UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
     32 {
     33   const Byte *p = (const Byte *)data;
     34   for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
     35     v = CRC_UPDATE_BYTE_2(v, *p);
     36   for (; size >= 8; size -= 8, p += 8)
     37   {
     38     UInt32 d;
     39     v ^= *(const UInt32 *)p;
     40     v =
     41           (table + 0x700)[((v      ) & 0xFF)]
     42         ^ (table + 0x600)[((v >>  8) & 0xFF)]
     43         ^ (table + 0x500)[((v >> 16) & 0xFF)]
     44         ^ (table + 0x400)[((v >> 24))];
     45     d = *((const UInt32 *)p + 1);
     46     v ^=
     47           (table + 0x300)[((d      ) & 0xFF)]
     48         ^ (table + 0x200)[((d >>  8) & 0xFF)]
     49         ^ (table + 0x100)[((d >> 16) & 0xFF)]
     50         ^ (table + 0x000)[((d >> 24))];
     51   }
     52   for (; size > 0; size--, p++)
     53     v = CRC_UPDATE_BYTE_2(v, *p);
     54   return v;
     55 }
     56 
     57 #endif
     58 
     59 
     60 #ifndef MY_CPU_LE
     61 
     62 #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
     63 
     64 #define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
     65 
     66 UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
     67 {
     68   const Byte *p = (const Byte *)data;
     69   table += 0x100;
     70   v = CRC_UINT32_SWAP(v);
     71   for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
     72     v = CRC_UPDATE_BYTE_2_BE(v, *p);
     73   for (; size >= 4; size -= 4, p += 4)
     74   {
     75     v ^= *(const UInt32 *)p;
     76     v =
     77           (table + 0x000)[((v      ) & 0xFF)]
     78         ^ (table + 0x100)[((v >>  8) & 0xFF)]
     79         ^ (table + 0x200)[((v >> 16) & 0xFF)]
     80         ^ (table + 0x300)[((v >> 24))];
     81   }
     82   for (; size > 0; size--, p++)
     83     v = CRC_UPDATE_BYTE_2_BE(v, *p);
     84   return CRC_UINT32_SWAP(v);
     85 }
     86 
     87 UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
     88 {
     89   const Byte *p = (const Byte *)data;
     90   table += 0x100;
     91   v = CRC_UINT32_SWAP(v);
     92   for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
     93     v = CRC_UPDATE_BYTE_2_BE(v, *p);
     94   for (; size >= 8; size -= 8, p += 8)
     95   {
     96     UInt32 d;
     97     v ^= *(const UInt32 *)p;
     98     v =
     99           (table + 0x400)[((v      ) & 0xFF)]
    100         ^ (table + 0x500)[((v >>  8) & 0xFF)]
    101         ^ (table + 0x600)[((v >> 16) & 0xFF)]
    102         ^ (table + 0x700)[((v >> 24))];
    103     d = *((const UInt32 *)p + 1);
    104     v ^=
    105           (table + 0x000)[((d      ) & 0xFF)]
    106         ^ (table + 0x100)[((d >>  8) & 0xFF)]
    107         ^ (table + 0x200)[((d >> 16) & 0xFF)]
    108         ^ (table + 0x300)[((d >> 24))];
    109   }
    110   for (; size > 0; size--, p++)
    111     v = CRC_UPDATE_BYTE_2_BE(v, *p);
    112   return CRC_UINT32_SWAP(v);
    113 }
    114 
    115 #endif
    116