7
7
; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
8
8
;===========================================================================
9
9
; crc_i386.asm, optimized CRC calculation function for Zip and UnZip,
10
; created by Paul Kienitz and Christian Spieler. Last revised 16 Jan 2005.
10
; created by Paul Kienitz and Christian Spieler. Last revised 07 Jan 2007.
12
12
; Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
13
13
; fixed to assemble with masm by not using .model directive which makes
47
47
; Enabled the 686 build by default, because there are hardly any pre-686 CPUs
48
48
; in serious use nowadays. (See the 12-Oct-97 note above.)
50
; Revised 03-Jan-2006, Chr. Spieler
51
; Enlarged unrolling loops to "do 16 bytes per turn"; optimized access to
52
; data buffer in loop body (adjust pointer only once in loop body and use
53
; offsets to access each item); added additional support for the "unfolded
54
; tables" optimization variant (enabled by IZ_CRCOPTIM_UNFOLDTBL).
56
; Revised 07-Jan-2007, Chr. Spieler
57
; Recognize additional conditional flag CRC_TABLE_ONLY that prevents
58
; compilation of the crc32() function.
50
60
; FLAT memory model assumed.
52
62
; Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
123
135
ELSE ; __686 : optimize for Pentium Pro, Pentium II and compatible CPUs
125
movzx ebx,al ; tmp = c & 0xFF
126
shr eax,8 ; c = (c >> 8)
127
xor eax,[edi+ebx*4] ; ^ table[tmp]
137
movzx ebx,al ; tmp = c & 0xFF
138
shr eax,8 ; c = (c >> 8)
139
xor eax,[edi+ebx*4] ; ^ table[tmp]
130
142
Do_CRC_byte MACRO
131
xor al, byte ptr [esi] ; c ^= *buf
133
Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
143
xor al, byte ptr [esi] ; c ^= *buf
145
Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
147
Do_CRC_byteof MACRO ofs
148
xor al, byte ptr [esi+ofs] ; c ^= *(buf+ofs)
149
Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
135
151
IFNDEF NO_32_BIT_LOADS
152
IFDEF IZ_CRCOPTIM_UNFOLDTBL
153
; the edx register is needed in crc calculation
157
movzx ebx,al ; tmp = c & 0xFF
158
mov edx,[edi+ebx*4+3072] ; table[256*3+tmp]
159
movzx ebx,ah ; tmp = (c>>8) & 0xFF
161
xor edx,[edi+ebx*4+2048] ; ^ table[256*2+tmp]
162
movzx ebx,al ; tmp = (c>>16) & 0xFF
163
shr eax,8 ; tmp = (c>>24)
164
xor edx,[edi+ebx*4+1024] ; ^ table[256*1+tmp]
165
mov eax,[edi+eax*4] ; ^ table[256*0+tmp]
168
UpdCRC_dword_sh MACRO dwPtrIncr
169
movzx ebx,al ; tmp = c & 0xFF
170
mov edx,[edi+ebx*4+3072] ; table[256*3+tmp]
171
movzx ebx,ah ; tmp = (c>>8) & 0xFF
172
xor edx,[edi+ebx*4+2048] ; ^ table[256*2+tmp]
174
movzx ebx,al ; tmp = (c>>16) & 0xFF
175
add esi, 4*dwPtrIncr ; ((ulg *)buf) += dwPtrIncr
176
shr eax,8 ; tmp = (c>>24)
177
xor edx,[edi+ebx*4+1024] ; ^ table[256*1+tmp]
178
mov eax,[edi+eax*4] ; ^ table[256*0+tmp]
181
ELSE ; IZ_CRCOPTIM_UNFOLDTBL
182
; the edx register is not needed anywhere else
191
UpdCRC_dword_sh MACRO dwPtrIncr
194
add esi, 4*dwPtrIncr ; ((ulg *)buf) += dwPtrIncr
198
ENDIF ; ?IZ_CRCOPTIM_UNFOLDTBL
136
199
Do_CRC_dword MACRO
137
xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
138
add esi, 4 ; ((ulg *)buf)++
200
xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
201
UpdCRC_dword_sh 1 ; ... ((ulg *)buf)++
204
xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
206
xor eax, dword ptr [esi+4] ; c ^= *((ulg *)buf+1)
208
xor eax, dword ptr [esi+8] ; c ^= *((ulg *)buf+2)
210
xor eax, dword ptr [esi+12] ; c ^= *((ulg *)buf]+3
211
UpdCRC_dword_sh 4 ; ... ((ulg *)buf)+=4
144
213
ENDIF ; !NO_32_BIT_LOADS
162
mov esi,Arg2 ; 2nd arg: uch *buf
163
sub eax,eax ;> if (!buf)
164
test esi,esi ;> return 0;
231
mov esi,Arg2 ; 2nd arg: uch *buf
232
sub eax,eax ;> if (!buf)
233
test esi,esi ;> return 0;
167
236
call _get_crc_table
169
mov eax,Arg1 ; 1st arg: ulg crc
238
mov eax,Arg1 ; 1st arg: ulg crc
171
sub ebx,ebx ; ebx=0; make bl usable as a dword
240
sub ebx,ebx ; ebx=0; make bl usable as a dword
173
mov ecx,Arg3 ; 3rd arg: extent len
242
mov ecx,Arg3 ; 3rd arg: extent len
177
246
IFNDEF NO_UNROLLED_LOOPS
179
248
IFNDEF NO_32_BIT_LOADS
181
test esi,3 ; align buf pointer on next
182
jz SHORT aligned_now ; dword boundary
250
test esi,3 ; align buf pointer on next
251
jz SHORT aligned_now ; dword boundary
187
256
ENDIF ; !NO_32_BIT_LOADS
188
mov edx,ecx ; save len in edx
189
shr ecx,3 ; ecx = len / 8
257
mov SavLen,ecx ; save current len for later
258
shr ecx,4 ; ecx = len / 16
192
261
; align loop head at start of 486 internal cache line !!
196
265
IFNDEF NO_32_BIT_LOADS
199
267
ELSE ; NO_32_BIT_LOADS
284
add esi, 16 ; buf += 16
208
285
ENDIF ; ?NO_32_BIT_LOADS
213
and ecx,000000007H ; ecx = len % 8
290
and ecx,00000000FH ; ecx = len % 16
291
IFNDEF NO_32_BIT_LOADS
292
shr ecx,2 ; ecx = len / 4
300
and ecx,000000003H ; ecx = len % 4
301
ENDIF ; !NO_32_BIT_LOADS
214
302
ENDIF ; !NO_UNROLLED_LOOPS
215
jz SHORT bail ;> if (len)
303
jz SHORT bail ;> if (len)
217
305
; align loop head at start of 486 internal cache line !!
221
Do_CRC_byte ; c = CRC32(c, *buf++);
222
dec ecx ;> } while (--len);
309
Do_CRC_byte ; c = CRC32(c,*buf++,crctab);
310
dec ecx ;> } while (--len);
226
not eax ;> return ~c;
314
not eax ;> return ~c;