1370b324cSopenharmony_ci/* XzCrc64.c -- CRC64 calculation
2370b324cSopenharmony_ci2023-04-02 : Igor Pavlov : Public domain */
3370b324cSopenharmony_ci
4370b324cSopenharmony_ci#include "Precomp.h"
5370b324cSopenharmony_ci
6370b324cSopenharmony_ci#include "XzCrc64.h"
7370b324cSopenharmony_ci#include "CpuArch.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci#ifdef MY_CPU_LE
12370b324cSopenharmony_ci  #define CRC64_NUM_TABLES 4
13370b324cSopenharmony_ci#else
14370b324cSopenharmony_ci  #define CRC64_NUM_TABLES 5
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci  UInt64 Z7_FASTCALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
17370b324cSopenharmony_ci#endif
18370b324cSopenharmony_ci
19370b324cSopenharmony_ci#ifndef MY_CPU_BE
20370b324cSopenharmony_ci  UInt64 Z7_FASTCALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
21370b324cSopenharmony_ci#endif
22370b324cSopenharmony_ci
23370b324cSopenharmony_citypedef UInt64 (Z7_FASTCALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
24370b324cSopenharmony_ci
25370b324cSopenharmony_cistatic CRC64_FUNC g_Crc64Update;
26370b324cSopenharmony_ciUInt64 g_Crc64Table[256 * CRC64_NUM_TABLES];
27370b324cSopenharmony_ci
28370b324cSopenharmony_ciUInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size)
29370b324cSopenharmony_ci{
30370b324cSopenharmony_ci  return g_Crc64Update(v, data, size, g_Crc64Table);
31370b324cSopenharmony_ci}
32370b324cSopenharmony_ci
33370b324cSopenharmony_ciUInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size)
34370b324cSopenharmony_ci{
35370b324cSopenharmony_ci  return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL;
36370b324cSopenharmony_ci}
37370b324cSopenharmony_ci
38370b324cSopenharmony_civoid Z7_FASTCALL Crc64GenerateTable(void)
39370b324cSopenharmony_ci{
40370b324cSopenharmony_ci  UInt32 i;
41370b324cSopenharmony_ci  for (i = 0; i < 256; i++)
42370b324cSopenharmony_ci  {
43370b324cSopenharmony_ci    UInt64 r = i;
44370b324cSopenharmony_ci    unsigned j;
45370b324cSopenharmony_ci    for (j = 0; j < 8; j++)
46370b324cSopenharmony_ci      r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1)));
47370b324cSopenharmony_ci    g_Crc64Table[i] = r;
48370b324cSopenharmony_ci  }
49370b324cSopenharmony_ci  for (i = 256; i < 256 * CRC64_NUM_TABLES; i++)
50370b324cSopenharmony_ci  {
51370b324cSopenharmony_ci    const UInt64 r = g_Crc64Table[(size_t)i - 256];
52370b324cSopenharmony_ci    g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
53370b324cSopenharmony_ci  }
54370b324cSopenharmony_ci
55370b324cSopenharmony_ci  #ifdef MY_CPU_LE
56370b324cSopenharmony_ci
57370b324cSopenharmony_ci  g_Crc64Update = XzCrc64UpdateT4;
58370b324cSopenharmony_ci
59370b324cSopenharmony_ci  #else
60370b324cSopenharmony_ci  {
61370b324cSopenharmony_ci    #ifndef MY_CPU_BE
62370b324cSopenharmony_ci    UInt32 k = 1;
63370b324cSopenharmony_ci    if (*(const Byte *)&k == 1)
64370b324cSopenharmony_ci      g_Crc64Update = XzCrc64UpdateT4;
65370b324cSopenharmony_ci    else
66370b324cSopenharmony_ci    #endif
67370b324cSopenharmony_ci    {
68370b324cSopenharmony_ci      for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--)
69370b324cSopenharmony_ci      {
70370b324cSopenharmony_ci        const UInt64 x = g_Crc64Table[(size_t)i - 256];
71370b324cSopenharmony_ci        g_Crc64Table[i] = Z7_BSWAP64(x);
72370b324cSopenharmony_ci      }
73370b324cSopenharmony_ci      g_Crc64Update = XzCrc64UpdateT1_BeT4;
74370b324cSopenharmony_ci    }
75370b324cSopenharmony_ci  }
76370b324cSopenharmony_ci  #endif
77370b324cSopenharmony_ci}
78370b324cSopenharmony_ci
79370b324cSopenharmony_ci#undef kCrc64Poly
80370b324cSopenharmony_ci#undef CRC64_NUM_TABLES
81