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 #include <asm/regdef.h>
35
36 .set noat
37 .set noreorder
38
39 .text
40
41
42
43
44
45
46
47 .ent stxcpy_aligned
48 .align 4
49 stxcpy_aligned:
50 .frame sp, 0, t9
51 .prologue 0
52
53
54
55
56
57
58 lda t2, -1 # E : build a mask against false zero
59 mskqh t2, a1, t2 # U : detection in the src word (stall)
60 mskqh t1, a1, t3 # U :
61 ornot t1, t2, t2 # E : (stall)
62
63 mskql t0, a1, t0 # U : assemble the first output word
64 cmpbge zero, t2, t8 # E : bits set iff null found
65 or t0, t3, t1 # E : (stall)
66 bne t8, $a_eos # U : (stall)
67
68
69
70
71
72
73 $a_loop:
74 stq_u t1, 0(a0) # L :
75 addq a0, 8, a0 # E :
76 nop
77 nop
78
79 ldq_u t1, 0(a1) # L : Latency=3
80 addq a1, 8, a1 # E :
81 cmpbge zero, t1, t8 # E : (3 cycle stall)
82 beq t8, $a_loop # U : (stall for t8)
83
84
85
86
87
88 $a_eos:
89 negq t8, t6 # E : find low bit set
90 and t8, t6, t12 # E : (stall)
91
92
93 and t12, 0x80, t6 # E : (stall)
94 bne t6, 1f # U : (stall)
95
96
97
98 ldq_u t0, 0(a0) # L : Latency=3
99 subq t12, 1, t6 # E :
100 zapnot t1, t6, t1 # U : clear src bytes >= null (stall)
101 or t12, t6, t8 # E : (stall)
102
103 zap t0, t8, t0 # E : clear dst bytes <= null
104 or t0, t1, t1 # E : (stall)
105 nop
106 nop
107
108 1: stq_u t1, 0(a0) # L :
109 ret (t9) # L0 : Latency=3
110 nop
111 nop
112
113 .end stxcpy_aligned
114
115 .align 4
116 .ent __stxcpy
117 .globl __stxcpy
118 __stxcpy:
119 .frame sp, 0, t9
120 .prologue 0
121
122
123 xor a0, a1, t0 # E :
124 unop # E :
125 and t0, 7, t0 # E : (stall)
126 bne t0, $unaligned # U : (stall)
127
128
129 ldq_u t1, 0(a1) # L : load first src word
130 and a0, 7, t0 # E : take care not to load a word ...
131 addq a1, 8, a1 # E :
132 beq t0, stxcpy_aligned # U : ... if we wont need it (stall)
133
134 ldq_u t0, 0(a0) # L :
135 br stxcpy_aligned # L0 : Latency=3
136 nop
137 nop
138
139
140
141
142
143
144 .align 4
145 $u_head:
146
147
148
149
150
151
152
153
154
155 ldq_u t2, 8(a1) # L :
156 addq a1, 8, a1 # E :
157 extql t1, a1, t1 # U : (stall on a1)
158 extqh t2, a1, t4 # U : (stall on a1)
159
160 mskql t0, a0, t0 # U :
161 or t1, t4, t1 # E :
162 mskqh t1, a0, t1 # U : (stall on t1)
163 or t0, t1, t1 # E : (stall on t1)
164
165 or t1, t6, t6 # E :
166 cmpbge zero, t6, t8 # E : (stall)
167 lda t6, -1 # E : for masking just below
168 bne t8, $u_final # U : (stall)
169
170 mskql t6, a1, t6 # U : mask out the bits we have
171 or t6, t2, t2 # E : already extracted before (stall)
172 cmpbge zero, t2, t8 # E : testing eos (stall)
173 bne t8, $u_late_head_exit # U : (stall)
174
175
176
177
178 stq_u t1, 0(a0) # L : store first output word
179 addq a0, 8, a0 # E :
180 extql t2, a1, t0 # U : position ho-bits of lo word
181 ldq_u t2, 8(a1) # U : read next high-order source word
182
183 addq a1, 8, a1 # E :
184 cmpbge zero, t2, t8 # E : (stall for t2)
185 nop # E :
186 bne t8, $u_eos # U : (stall)
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 .align 3
202 $u_loop:
203 extqh t2, a1, t1 # U : extract high bits for current word
204 addq a1, 8, a1 # E : (stall)
205 extql t2, a1, t3 # U : extract low bits for next time (stall)
206 addq a0, 8, a0 # E :
207
208 or t0, t1, t1 # E : current dst word now complete
209 ldq_u t2, 0(a1) # L : Latency=3 load high word for next time
210 stq_u t1, -8(a0) # L : save the current word (stall)
211 mov t3, t0 # E :
212
213 cmpbge zero, t2, t8 # E : test new word for eos
214 beq t8, $u_loop # U : (stall)
215 nop
216 nop
217
218
219
220
221
222
223
224
225
226 $u_eos:
227 extqh t2, a1, t1 # U :
228 or t0, t1, t1 # E : first (partial) source word complete (stall)
229 cmpbge zero, t1, t8 # E : is the null in this first bit? (stall)
230 bne t8, $u_final # U : (stall)
231
232 $u_late_head_exit:
233 stq_u t1, 0(a0) # L : the null was in the high-order bits
234 addq a0, 8, a0 # E :
235 extql t2, a1, t1 # U :
236 cmpbge zero, t1, t8 # E : (stall)
237
238
239
240
241
242 $u_final:
243 negq t8, t6 # E : isolate low bit set
244 and t6, t8, t12 # E : (stall)
245 and t12, 0x80, t6 # E : avoid dest word load if we can (stall)
246 bne t6, 1f # U : (stall)
247
248 ldq_u t0, 0(a0) # E :
249 subq t12, 1, t6 # E :
250 or t6, t12, t8 # E : (stall)
251 zapnot t1, t6, t1 # U : kill source bytes >= null (stall)
252
253 zap t0, t8, t0 # U : kill dest bytes <= null (2 cycle data stall)
254 or t0, t1, t1 # E : (stall)
255 nop
256 nop
257
258 1: stq_u t1, 0(a0) # L :
259 ret (t9) # L0 : Latency=3
260 nop
261 nop
262
263
264 .align 4
265 $unaligned:
266
267 ldq_u t1, 0(a1) # L : load first source word
268 and a0, 7, t4 # E : find dest misalignment
269 and a1, 7, t5 # E : find src misalignment
270
271
272 mov zero, t0 # E :
273
274 mov zero, t6 # E :
275 beq t4, 1f # U :
276 ldq_u t0, 0(a0) # L :
277 lda t6, -1 # E :
278
279 mskql t6, a0, t6 # U :
280 nop
281 nop
282 nop
283 1:
284 subq a1, t4, a1 # E : sub dest misalignment from src addr
285
286
287 cmplt t4, t5, t12 # E :
288 beq t12, $u_head # U :
289 lda t2, -1 # E : mask out leading garbage in source
290
291 mskqh t2, t5, t2 # U :
292 ornot t1, t2, t3 # E : (stall)
293 cmpbge zero, t3, t8 # E : is there a zero? (stall)
294 beq t8, $u_head # U : (stall)
295
296
297
298
299
300
301 ldq_u t0, 0(a0) # L :
302 negq t8, t6 # E : build bitmask of bytes <= zero
303 and t6, t8, t12 # E : (stall)
304 and a1, 7, t5 # E :
305
306 subq t12, 1, t6 # E :
307 or t6, t12, t8 # E : (stall)
308 srl t12, t5, t12 # U : adjust final null return value
309 zapnot t2, t8, t2 # U : prepare source word; mirror changes (stall)
310
311 and t1, t2, t1 # E : to source validity mask
312 extql t2, a1, t2 # U :
313 extql t1, a1, t1 # U : (stall)
314 andnot t0, t2, t0 # .. e1 : zero place for source to reside (stall)
315
316 or t0, t1, t1 # e1 : and put it there
317 stq_u t1, 0(a0) # .. e0 : (stall)
318 ret (t9) # e1 :
319 nop
320
321 .end __stxcpy
322