-
Notifications
You must be signed in to change notification settings - Fork 28
/
crc32c-gas.S
executable file
·241 lines (176 loc) · 3.47 KB
/
crc32c-gas.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/* Copyright (c) Mark Harmstone 2020
*
* This file is part of WinBtrfs.
*
* WinBtrfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public Licence as published by
* the Free Software Foundation, either version 3 of the Licence, or
* (at your option) any later version.
*
* WinBtrfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public Licence for more details.
*
* You should have received a copy of the GNU Lesser General Public Licence
* along with WinBtrfs. If not, see <http:https://www.gnu.org/licenses/>. */
#ifdef __i386__
.intel_syntax noprefix
#ifdef __MINGW32__
.extern _crctable
.global _calc_crc32c_sw@12
.global _calc_crc32c_hw@12
#else
.extern crctable
.global calc_crc32c_sw
.global calc_crc32c_hw
#endif
/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
#ifdef __MINGW32__
_calc_crc32c_sw@12:
#else
calc_crc32c_sw:
#endif
push ebp
mov ebp, esp
push esi
push ebx
mov eax, [ebp+8]
mov edx, [ebp+12]
mov ebx, [ebp+16]
/* eax = crc / seed
* ebx = len
* esi = tmp
* edx = buf
* ecx = tmp2 */
crcloop:
test ebx, ebx
jz crcend
mov esi, eax
shr esi, 8
mov cl, byte ptr [edx]
xor al, cl
and eax, 255
shl eax, 2
#ifdef __MINGW32__
mov eax, [_crctable + eax]
#else
mov eax, [crctable + eax]
#endif
xor eax, esi
inc edx
dec ebx
jmp crcloop
crcend:
pop ebx
pop esi
pop ebp
ret 12
/****************************************************/
/* uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
#ifdef __MINGW32__
_calc_crc32c_hw@12:
#else
calc_crc32c_hw:
#endif
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov edx, [ebp+12]
mov ecx, [ebp+16]
/* eax = crc / seed
* ecx = len
* edx = buf */
crchw_loop:
cmp ecx, 4
jl crchw_stragglers
crc32 eax, dword ptr [edx]
add edx, 4
sub ecx, 4
jmp crchw_loop
crchw_stragglers:
cmp ecx, 2
jl crchw_stragglers2
crc32 eax, word ptr [edx]
add edx, 2
sub ecx, 2
crchw_stragglers2:
test ecx, ecx
jz crchw_end
crc32 eax, byte ptr [edx]
inc edx
dec ecx
jmp crchw_stragglers2
crchw_end:
pop ebp
ret 12
#elif defined(__x86_64__)
.intel_syntax noprefix
.extern crctable
.global calc_crc32c_sw
.global calc_crc32c_hw
/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
calc_crc32c_sw:
/* rax = crc / seed
* rdx = buf
* r8 = len
* rcx = tmp
* r10 = tmp2
* r11 = crctable */
lea r11, [rip + crctable]
mov rax, rcx
crcloop:
test r8, r8
jz crcend
mov rcx, rax
shr rcx, 8
mov r10b, byte ptr [rdx]
xor al, r10b
and rax, 255
shl rax, 2
mov eax, [r11 + rax]
xor rax, rcx
inc rdx
dec r8
jmp crcloop
crcend:
ret
/****************************************************/
/* uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
calc_crc32c_hw:
/* rax = crc / seed
* rdx = buf
* r8 = len */
mov rax, rcx
crchw_loop:
cmp r8, 8
jl crchw_stragglers
crc32 rax, qword ptr [rdx]
add rdx, 8
sub r8, 8
jmp crchw_loop
crchw_stragglers:
cmp r8, 4
jl crchw_stragglers2
crc32 eax, dword ptr [rdx]
add rdx, 4
sub r8, 4
crchw_stragglers2:
cmp r8, 2
jl crchw_stragglers3
crc32 eax, word ptr [rdx]
add rdx, 2
sub r8, 2
crchw_stragglers3:
test r8, r8
jz crchw_end
crc32 eax, byte ptr [rdx]
inc rdx
dec r8
jmp crchw_stragglers3
crchw_end:
ret
#endif
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif