diff options
Diffstat (limited to 'C/XzCrc64.c')
-rw-r--r-- | C/XzCrc64.c | 122 |
1 files changed, 91 insertions, 31 deletions
diff --git a/C/XzCrc64.c b/C/XzCrc64.c index c2fad6c..94fc1af 100644 --- a/C/XzCrc64.c +++ b/C/XzCrc64.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* XzCrc64.c -- CRC64 calculation | 1 | /* XzCrc64.c -- CRC64 calculation |
2 | 2023-04-02 : Igor Pavlov : Public domain */ | 2 | 2023-12-08 : Igor Pavlov : Public domain */ |
3 | 3 | ||
4 | #include "Precomp.h" | 4 | #include "Precomp.h" |
5 | 5 | ||
@@ -8,36 +8,76 @@ | |||
8 | 8 | ||
9 | #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) | 9 | #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) |
10 | 10 | ||
11 | #ifdef MY_CPU_LE | 11 | // for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu |
12 | #define CRC64_NUM_TABLES 4 | 12 | // #define Z7_CRC64_DEBUG_BE |
13 | #ifdef Z7_CRC64_DEBUG_BE | ||
14 | #undef MY_CPU_LE | ||
15 | #define MY_CPU_BE | ||
16 | #endif | ||
17 | |||
18 | #ifdef Z7_CRC64_NUM_TABLES | ||
19 | #define Z7_CRC64_NUM_TABLES_USE Z7_CRC64_NUM_TABLES | ||
13 | #else | 20 | #else |
14 | #define CRC64_NUM_TABLES 5 | 21 | #define Z7_CRC64_NUM_TABLES_USE 12 |
22 | #endif | ||
15 | 23 | ||
16 | UInt64 Z7_FASTCALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); | 24 | #if Z7_CRC64_NUM_TABLES_USE < 1 |
25 | #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES | ||
17 | #endif | 26 | #endif |
18 | 27 | ||
28 | |||
29 | #if Z7_CRC64_NUM_TABLES_USE != 1 | ||
30 | |||
19 | #ifndef MY_CPU_BE | 31 | #ifndef MY_CPU_BE |
20 | UInt64 Z7_FASTCALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); | 32 | #define FUNC_NAME_LE_2(s) XzCrc64UpdateT ## s |
33 | #define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s) | ||
34 | #define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC64_NUM_TABLES_USE) | ||
35 | UInt64 Z7_FASTCALL FUNC_NAME_LE (UInt64 v, const void *data, size_t size, const UInt64 *table); | ||
36 | #endif | ||
37 | #ifndef MY_CPU_LE | ||
38 | #define FUNC_NAME_BE_2(s) XzCrc64UpdateBeT ## s | ||
39 | #define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s) | ||
40 | #define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC64_NUM_TABLES_USE) | ||
41 | UInt64 Z7_FASTCALL FUNC_NAME_BE (UInt64 v, const void *data, size_t size, const UInt64 *table); | ||
21 | #endif | 42 | #endif |
22 | 43 | ||
23 | typedef UInt64 (Z7_FASTCALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); | 44 | #if defined(MY_CPU_LE) |
45 | #define FUNC_REF FUNC_NAME_LE | ||
46 | #elif defined(MY_CPU_BE) | ||
47 | #define FUNC_REF FUNC_NAME_BE | ||
48 | #else | ||
49 | #define FUNC_REF g_Crc64Update | ||
50 | static UInt64 (Z7_FASTCALL *FUNC_REF)(UInt64 v, const void *data, size_t size, const UInt64 *table); | ||
51 | #endif | ||
52 | |||
53 | #endif | ||
54 | |||
55 | |||
56 | MY_ALIGN(64) | ||
57 | static UInt64 g_Crc64Table[256 * Z7_CRC64_NUM_TABLES_USE]; | ||
24 | 58 | ||
25 | static CRC64_FUNC g_Crc64Update; | ||
26 | UInt64 g_Crc64Table[256 * CRC64_NUM_TABLES]; | ||
27 | 59 | ||
28 | UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size) | 60 | UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size) |
29 | { | 61 | { |
30 | return g_Crc64Update(v, data, size, g_Crc64Table); | 62 | #if Z7_CRC64_NUM_TABLES_USE == 1 |
63 | #define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) | ||
64 | const UInt64 *table = g_Crc64Table; | ||
65 | const Byte *p = (const Byte *)data; | ||
66 | const Byte *lim = p + size; | ||
67 | for (; p != lim; p++) | ||
68 | v = CRC64_UPDATE_BYTE_2(v, *p); | ||
69 | return v; | ||
70 | #undef CRC64_UPDATE_BYTE_2 | ||
71 | #else | ||
72 | return FUNC_REF (v, data, size, g_Crc64Table); | ||
73 | #endif | ||
31 | } | 74 | } |
32 | 75 | ||
33 | UInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size) | ||
34 | { | ||
35 | return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; | ||
36 | } | ||
37 | 76 | ||
77 | Z7_NO_INLINE | ||
38 | void Z7_FASTCALL Crc64GenerateTable(void) | 78 | void Z7_FASTCALL Crc64GenerateTable(void) |
39 | { | 79 | { |
40 | UInt32 i; | 80 | unsigned i; |
41 | for (i = 0; i < 256; i++) | 81 | for (i = 0; i < 256; i++) |
42 | { | 82 | { |
43 | UInt64 r = i; | 83 | UInt64 r = i; |
@@ -46,35 +86,55 @@ void Z7_FASTCALL Crc64GenerateTable(void) | |||
46 | r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1))); | 86 | r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1))); |
47 | g_Crc64Table[i] = r; | 87 | g_Crc64Table[i] = r; |
48 | } | 88 | } |
49 | for (i = 256; i < 256 * CRC64_NUM_TABLES; i++) | 89 | |
90 | #if Z7_CRC64_NUM_TABLES_USE != 1 | ||
91 | #if 1 || 1 && defined(MY_CPU_X86) // low register count | ||
92 | for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i++) | ||
50 | { | 93 | { |
51 | const UInt64 r = g_Crc64Table[(size_t)i - 256]; | 94 | const UInt64 r0 = g_Crc64Table[(size_t)i]; |
52 | g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); | 95 | g_Crc64Table[(size_t)i + 256] = g_Crc64Table[(Byte)r0] ^ (r0 >> 8); |
53 | } | 96 | } |
54 | 97 | #else | |
55 | #ifdef MY_CPU_LE | 98 | for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i += 2) |
56 | 99 | { | |
57 | g_Crc64Update = XzCrc64UpdateT4; | 100 | UInt64 r0 = g_Crc64Table[(size_t)(i) ]; |
101 | UInt64 r1 = g_Crc64Table[(size_t)(i) + 1]; | ||
102 | r0 = g_Crc64Table[(Byte)r0] ^ (r0 >> 8); | ||
103 | r1 = g_Crc64Table[(Byte)r1] ^ (r1 >> 8); | ||
104 | g_Crc64Table[(size_t)i + 256 ] = r0; | ||
105 | g_Crc64Table[(size_t)i + 256 + 1] = r1; | ||
106 | } | ||
107 | #endif | ||
58 | 108 | ||
59 | #else | 109 | #ifndef MY_CPU_LE |
60 | { | 110 | { |
61 | #ifndef MY_CPU_BE | 111 | #ifndef MY_CPU_BE |
62 | UInt32 k = 1; | 112 | UInt32 k = 1; |
63 | if (*(const Byte *)&k == 1) | 113 | if (*(const Byte *)&k == 1) |
64 | g_Crc64Update = XzCrc64UpdateT4; | 114 | FUNC_REF = FUNC_NAME_LE; |
65 | else | 115 | else |
66 | #endif | 116 | #endif |
67 | { | 117 | { |
68 | for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--) | 118 | #ifndef MY_CPU_BE |
119 | FUNC_REF = FUNC_NAME_BE; | ||
120 | #endif | ||
121 | for (i = 0; i < 256 * Z7_CRC64_NUM_TABLES_USE; i++) | ||
69 | { | 122 | { |
70 | const UInt64 x = g_Crc64Table[(size_t)i - 256]; | 123 | const UInt64 x = g_Crc64Table[i]; |
71 | g_Crc64Table[i] = Z7_BSWAP64(x); | 124 | g_Crc64Table[i] = Z7_BSWAP64(x); |
72 | } | 125 | } |
73 | g_Crc64Update = XzCrc64UpdateT1_BeT4; | ||
74 | } | 126 | } |
75 | } | 127 | } |
76 | #endif | 128 | #endif // ndef MY_CPU_LE |
129 | #endif // Z7_CRC64_NUM_TABLES_USE != 1 | ||
77 | } | 130 | } |
78 | 131 | ||
79 | #undef kCrc64Poly | 132 | #undef kCrc64Poly |
80 | #undef CRC64_NUM_TABLES | 133 | #undef Z7_CRC64_NUM_TABLES_USE |
134 | #undef FUNC_REF | ||
135 | #undef FUNC_NAME_LE_2 | ||
136 | #undef FUNC_NAME_LE_1 | ||
137 | #undef FUNC_NAME_LE | ||
138 | #undef FUNC_NAME_BE_2 | ||
139 | #undef FUNC_NAME_BE_1 | ||
140 | #undef FUNC_NAME_BE | ||