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
|
#include <machine/asm.h>
/*
* a0: source address
* a1: length of the area to checksum
* a2: partial checksum
* a3: dst
*/
#define src a0
#define dst a3
#define sum v0
.text
.set noreorder
.macro CSUM_BIGCHUNK_AND_COPY offset
pref 0, (\offset+0x0)(a0)
ld t0, (\offset+0x00)(a0)
ld t1, (\offset+0x08)(a0)
.word 0x70481038 /*daddwc v0, v0, t0 */
.word 0x70491038 /*daddwc v0, v0, t1 */
ld t0, (\offset + 0x10)(a0)
ld t1, (\offset + 0x18)(a0)
.word 0x70481038 /* daddwc v0, v0, t0 */
.word 0x70491038 /*daddwc v0, v0, t1 */
.endm
small_csumcpy: /* unknown src alignment and < 8 bytes to go */
move a1, t2
andi t0, a1, 4
beqz t0, 1f
andi t0, a1, 2
ulw t1, (src) /* Still a full word to go */
daddiu src, 4
.word 0x70491038 /*daddwc v0, v0, t1 */
1: move t1, zero
beqz t0, 1f
andi t0, a1, 1
ulhu t1, (src) /* Still a halfword to go */
daddiu src, 2
1: beqz t0, 1f
sll t1, t1, 16
lbu t2, (src)
nop
#ifdef __MIPSEB__
sll t2, t2, 8
#endif
or t1, t2
1: .word 0x70491038 /*daddwc v0, v0, t1 */
.word 0x70461038 /*daddwc v0, v0, a2 */
.word 0x70401038 /*daddwc v0, v0, $0 */
/* Ideally at this point of time the status flag must be cleared */
dsll32 v1, sum, 0
.word 0x70431038 /*daddwc v0, v0, v1 */
dsrl32 sum, sum, 0
.word 0x70401038 /*daddwc v0, v0, zero */
/* fold the checksum */
sll v1, sum, 16
addu sum, v1
sltu v1, sum, v1
srl sum, sum, 16
addu sum, v1
1:
.set reorder
jr ra
.set noreorder
/* ------------------------------------------------------------------ */
.align 5
LEAF(xlr_csum_partial_nocopy)
move sum, zero
move t7, zero
sltiu t8, a1, 0x8
bnez t8, small_csumcpy /* < 8 bytes to copy */
move t2, a1
beqz a1, out
andi t7, src, 0x1 /* odd buffer? */
hword_align:
beqz t7, word_align
andi t8, src, 0x2
lbu t0, (src)
dsubu a1, a1, 0x1
.word 0x70481038 /*daddwc v0, v0, t0 */
daddu src, src, 0x1
andi t8, src, 0x2
word_align:
beqz t8, dword_align
sltiu t8, a1, 56
lhu t0, (src)
dsubu a1, a1, 0x2
.word 0x70481038 /*daddwc v0, v0, t0 */
sltiu t8, a1, 56
daddu src, src, 0x2
dword_align:
bnez t8, do_end_words
move t8, a1
andi t8, src, 0x4
beqz t8, qword_align
andi t8, src, 0x8
lw t0, 0x00(src)
dsubu a1, a1, 0x4
.word 0x70481038 /*daddwc v0, v0, t0 */
daddu src, src, 0x4
andi t8, src, 0x8
qword_align:
beqz t8, oword_align
andi t8, src, 0x10
ld t0, 0x00(src)
dsubu a1, a1, 0x8
.word 0x70481038 /*daddwc v0, v0, t0 */
daddu src, src, 0x8
andi t8, src, 0x10
oword_align:
beqz t8, begin_movement
dsrl t8, a1, 0x7
ld t3, 0x08(src)
ld t0, 0x00(src)
.word 0x704b1038 /*daddwc v0, v0, t3 */
.word 0x70481038 /*daddwc v0, v0, t0 */
dsubu a1, a1, 0x10
daddu src, src, 0x10
dsrl t8, a1, 0x7
begin_movement:
beqz t8, 1f
andi t2, a1, 0x40
move_128bytes:
pref 0, 0x20(a0)
pref 0, 0x40(a0)
pref 0, 0x60(a0)
CSUM_BIGCHUNK_AND_COPY(0x00)
CSUM_BIGCHUNK_AND_COPY(0x20)
CSUM_BIGCHUNK_AND_COPY(0x40)
CSUM_BIGCHUNK_AND_COPY(0x60)
dsubu t8, t8, 0x01
bnez t8, move_128bytes /* flag */
daddu src, src, 0x80
1:
beqz t2, 1f
andi t2, a1, 0x20
move_64bytes:
pref 0, 0x20(a0)
pref 0, 0x40(a0)
CSUM_BIGCHUNK_AND_COPY(0x00)
CSUM_BIGCHUNK_AND_COPY(0x20)
daddu src, src, 0x40
1:
beqz t2, do_end_words
andi t8, a1, 0x1c
move_32bytes:
pref 0, 0x20(a0)
CSUM_BIGCHUNK_AND_COPY(0x00)
andi t8, a1, 0x1c
daddu src, src, 0x20
do_end_words:
beqz t8, maybe_end_cruft
dsrl t8, t8, 0x2
end_words:
lw t0, (src)
dsubu t8, t8, 0x1
.word 0x70481038 /*daddwc v0, v0, t0 */
bnez t8, end_words
daddu src, src, 0x4
maybe_end_cruft:
andi t2, a1, 0x3
small_memcpy:
j small_csumcpy; move a1, t2
beqz t2, out
move a1, t2
end_bytes:
lb t0, (src)
dsubu a1, a1, 0x1
bnez a2, end_bytes
daddu src, src, 0x1
out:
jr ra
move v0, sum
END(xlr_csum_partial_nocopy)
|