-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrc64.s
135 lines (110 loc) · 4.17 KB
/
crc64.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
.global crc64
.global crc64_init
.bss
.lcomm crc64_lookup_table, 256 * 8
.text
//
// CRC64_ECMA_182
//
// arguments:
// x0: char* source
// x1: unsigned long length
//
// return:
// x0: unsigned long result
//
crc64:
sub sp, sp, 0x30
str x0, [sp] // source
str x1, [sp, 0x8] // length
str xzr, [sp, 0x10] // result
str xzr, [sp, 0x18] // i
b crc64_loop_check
crc64_loop:
ldr x0, [sp, 0x10]
lsr x1, x0, 0x38 // result >> 56
ldr x0, [sp]
add x2, x0, 0x1 // source++
str x2, [sp]
ldrb w0, [x0] // byte
and x0, x0, 0xff
eor x0, x1, x0 // result ^ byte
and x0, x0, 0xff
str x0, [sp, 0x20] // byte
adrp x0, crc64_lookup_table
add x0, x0, :lo12:crc64_lookup_table
ldr x1, [sp, 0x20]
ldr x1, [x0, x1, lsl 3] // crc64_lookup_table[byte]
ldr x0, [sp, 0x10]
lsl x0, x0, 0x8 // result << 8
eor x0, x1, x0 // x1 ^ x0
str x0, [sp, 0x10]
ldr x0, [sp, 0x18]
add x0, x0, 0x1 // i++
str x0, [sp, 0x18]
crc64_loop_check:
ldr x1, [sp, 0x18] // i
ldr x0, [sp, 0x8] // length
cmp x1, x0 // i == length
bcc crc64_loop
ldr x0, [sp, 0x10]
add sp, sp, 0x30
ret
//
// initialize lookup table
//
crc64_init:
sub sp, sp, 0x20
str wzr, [sp] // i = 0
b crc64_init_check
crc64_init_loop:
str xzr, [sp, 0x8] // crc = 0
ldrsw x0, [sp]
lsl x0, x0, 0x38 // i << 56
str x0, [sp, 0x10] // mask
str wzr, [sp, 0x4] // j = 0
b crc64_inner_loop_check
crc64_inner_loop:
ldr x1, [sp, 0x8] // crc
ldr x0, [sp, 0x10] // mask
eor x0, x1, x0 // crc ^ mask
cmp x0, 0x0
bge crc64_inner_shift_crc
ldr x0, [sp, 0x8]
lsl x1, x0, 0x1 // crc << 1
mov x0, 0x3693
movk x0, 0xa9ea, lsl 16
movk x0, 0xe1eb, lsl 32
movk x0, 0x42f0, lsl 48
eor x0, x1, x0 // crc ^ 0x42F0E1EBA9EA3693
str x0, [sp, 0x8]
b crc64_inner_shift_mask
crc64_inner_shift_crc:
ldr x0, [sp, 0x8]
lsl x0, x0, 0x1 // crc <<= 1
str x0, [sp, 0x8]
crc64_inner_shift_mask:
ldr x0, [sp, 0x10]
lsl x0, x0, 0x1 // mask <<= 1
str x0, [sp, 0x10]
ldr w0, [sp, 0x4]
add w0, w0, 0x1 // j++
str w0, [sp, 0x4]
crc64_inner_loop_check:
ldr w0, [sp, 0x4]
cmp w0, 0x7 // j == 7
ble crc64_inner_loop
adrp x0, crc64_lookup_table
add x0, x0, :lo12:crc64_lookup_table
ldrsw x1, [sp] // i
ldr x2, [sp, 0x8] // crc
str x2, [x0, x1, lsl 3] // crc64_lookup_table[i] = crc
ldr w0, [sp]
add w0, w0, 0x1 // i++
str w0, [sp]
crc64_init_check:
ldr w0, [sp]
cmp w0, 0xff // i == 255
ble crc64_init_loop
add sp, sp, 0x20
ret