xref: /aosp_15_r20/external/lzma/C/7zCrcOpt.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 /* 7zCrcOpt.c -- CRC32 calculation (optimized functions)
2 2023-12-07 : Igor Pavlov : Public domain */
3 
4 #include "Precomp.h"
5 
6 #include "CpuArch.h"
7 
8 #if !defined(Z7_CRC_NUM_TABLES) || Z7_CRC_NUM_TABLES > 1
9 
10 // for debug only : define Z7_CRC_DEBUG_BE to test big-endian code in little-endian cpu
11 // #define Z7_CRC_DEBUG_BE
12 #ifdef Z7_CRC_DEBUG_BE
13 #undef MY_CPU_LE
14 #define MY_CPU_BE
15 #endif
16 
17 // the value Z7_CRC_NUM_TABLES_USE must be defined to same value as in 7zCrc.c
18 #ifdef Z7_CRC_NUM_TABLES
19 #define Z7_CRC_NUM_TABLES_USE  Z7_CRC_NUM_TABLES
20 #else
21 #define Z7_CRC_NUM_TABLES_USE  12
22 #endif
23 
24 #if Z7_CRC_NUM_TABLES_USE % 4     || \
25     Z7_CRC_NUM_TABLES_USE < 4 * 1 || \
26     Z7_CRC_NUM_TABLES_USE > 4 * 6
27   #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
28 #endif
29 
30 
31 #ifndef MY_CPU_BE
32 
33 #define CRC_UPDATE_BYTE_2(crc, b)  (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
34 
35 #define Q(n, d) \
36     ( (table + ((n) * 4 + 3) * 0x100)[(Byte)(d)] \
37     ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \
38     ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \
39     ^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] )
40 
41 #define R(a)  *((const UInt32 *)(const void *)p + (a))
42 
43 #define CRC_FUNC_PRE_LE2(step) \
44 UInt32 Z7_FASTCALL CrcUpdateT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
45 
46 #define CRC_FUNC_PRE_LE(step)   \
47         CRC_FUNC_PRE_LE2(step); \
48         CRC_FUNC_PRE_LE2(step)
49 
CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE)50 CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE)
51 {
52   const Byte *p = (const Byte *)data;
53   const Byte *lim;
54   for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
55     v = CRC_UPDATE_BYTE_2(v, *p);
56   lim = p + size;
57   if (size >= Z7_CRC_NUM_TABLES_USE)
58   {
59     lim -= Z7_CRC_NUM_TABLES_USE;
60     do
61     {
62       v ^= R(0);
63       {
64 #if Z7_CRC_NUM_TABLES_USE == 1 * 4
65         v = Q(0, v);
66 #else
67 #define U2(r, op) \
68         { d = R(r);  x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
69         UInt32 d, x;
70         U2(1, =)
71 #if Z7_CRC_NUM_TABLES_USE >= 3 * 4
72 #define U(r)  U2(r, ^=)
73         U(2)
74 #if Z7_CRC_NUM_TABLES_USE >= 4 * 4
75         U(3)
76 #if Z7_CRC_NUM_TABLES_USE >= 5 * 4
77         U(4)
78 #if Z7_CRC_NUM_TABLES_USE >= 6 * 4
79         U(5)
80 #if Z7_CRC_NUM_TABLES_USE >= 7 * 4
81 #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
82 #endif
83 #endif
84 #endif
85 #endif
86 #endif
87 #undef U
88 #undef U2
89         v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
90 #endif
91       }
92       p += Z7_CRC_NUM_TABLES_USE;
93     }
94     while (p <= lim);
95     lim += Z7_CRC_NUM_TABLES_USE;
96   }
97   for (; p < lim; p++)
98     v = CRC_UPDATE_BYTE_2(v, *p);
99   return v;
100 }
101 
102 #undef CRC_UPDATE_BYTE_2
103 #undef R
104 #undef Q
105 #undef CRC_FUNC_PRE_LE
106 #undef CRC_FUNC_PRE_LE2
107 
108 #endif
109 
110 
111 
112 
113 #ifndef MY_CPU_LE
114 
115 #define CRC_UPDATE_BYTE_2_BE(crc, b)  (table[((crc) >> 24) ^ (b)] ^ ((crc) << 8))
116 
117 #define Q(n, d) \
118     ( (table + ((n) * 4 + 0) * 0x100)[((d)) & 0xFF] \
119     ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \
120     ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \
121     ^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] )
122 
123 #ifdef Z7_CRC_DEBUG_BE
124   #define R(a)  GetBe32a((const UInt32 *)(const void *)p + (a))
125 #else
126   #define R(a)         *((const UInt32 *)(const void *)p + (a))
127 #endif
128 
129 
130 #define CRC_FUNC_PRE_BE2(step) \
131 UInt32 Z7_FASTCALL CrcUpdateT1_BeT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
132 
133 #define CRC_FUNC_PRE_BE(step)   \
134         CRC_FUNC_PRE_BE2(step); \
135         CRC_FUNC_PRE_BE2(step)
136 
CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE)137 CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE)
138 {
139   const Byte *p = (const Byte *)data;
140   const Byte *lim;
141   table += 0x100;
142   v = Z7_BSWAP32(v);
143   for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
144     v = CRC_UPDATE_BYTE_2_BE(v, *p);
145   lim = p + size;
146   if (size >= Z7_CRC_NUM_TABLES_USE)
147   {
148     lim -= Z7_CRC_NUM_TABLES_USE;
149     do
150     {
151       v ^= R(0);
152       {
153 #if Z7_CRC_NUM_TABLES_USE == 1 * 4
154         v = Q(0, v);
155 #else
156 #define U2(r, op) \
157         { d = R(r);  x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
158         UInt32 d, x;
159         U2(1, =)
160 #if Z7_CRC_NUM_TABLES_USE >= 3 * 4
161 #define U(r)  U2(r, ^=)
162         U(2)
163 #if Z7_CRC_NUM_TABLES_USE >= 4 * 4
164         U(3)
165 #if Z7_CRC_NUM_TABLES_USE >= 5 * 4
166         U(4)
167 #if Z7_CRC_NUM_TABLES_USE >= 6 * 4
168         U(5)
169 #if Z7_CRC_NUM_TABLES_USE >= 7 * 4
170 #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
171 #endif
172 #endif
173 #endif
174 #endif
175 #endif
176 #undef U
177 #undef U2
178         v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
179 #endif
180       }
181       p += Z7_CRC_NUM_TABLES_USE;
182     }
183     while (p <= lim);
184     lim += Z7_CRC_NUM_TABLES_USE;
185   }
186   for (; p < lim; p++)
187     v = CRC_UPDATE_BYTE_2_BE(v, *p);
188   return Z7_BSWAP32(v);
189 }
190 
191 #undef CRC_UPDATE_BYTE_2_BE
192 #undef R
193 #undef Q
194 #undef CRC_FUNC_PRE_BE
195 #undef CRC_FUNC_PRE_BE2
196 
197 #endif
198 #undef Z7_CRC_NUM_TABLES_USE
199 #endif
200