1#if defined(__x86_64__)
2.text
3
4
5.globl	_asm_RC4
6.private_extern _asm_RC4
7
8.p2align	4
9_asm_RC4:
10	orq	%rsi,%rsi
11	jne	L$entry
12	.byte	0xf3,0xc3
13L$entry:
14	pushq	%rbx
15	pushq	%r12
16	pushq	%r13
17L$prologue:
18	movq	%rsi,%r11
19	movq	%rdx,%r12
20	movq	%rcx,%r13
21	xorq	%r10,%r10
22	xorq	%rcx,%rcx
23
24	leaq	8(%rdi),%rdi
25	movb	-8(%rdi),%r10b
26	movb	-4(%rdi),%cl
27	cmpl	$-1,256(%rdi)
28	je	L$RC4_CHAR
29	movl	_OPENSSL_ia32cap_P(%rip),%r8d
30	xorq	%rbx,%rbx
31	incb	%r10b
32	subq	%r10,%rbx
33	subq	%r12,%r13
34	movl	(%rdi,%r10,4),%eax
35	testq	$-16,%r11
36	jz	L$loop1
37	btl	$30,%r8d
38	jc	L$intel
39	andq	$7,%rbx
40	leaq	1(%r10),%rsi
41	jz	L$oop8
42	subq	%rbx,%r11
43L$oop8_warmup:
44	addb	%al,%cl
45	movl	(%rdi,%rcx,4),%edx
46	movl	%eax,(%rdi,%rcx,4)
47	movl	%edx,(%rdi,%r10,4)
48	addb	%dl,%al
49	incb	%r10b
50	movl	(%rdi,%rax,4),%edx
51	movl	(%rdi,%r10,4),%eax
52	xorb	(%r12),%dl
53	movb	%dl,(%r12,%r13,1)
54	leaq	1(%r12),%r12
55	decq	%rbx
56	jnz	L$oop8_warmup
57
58	leaq	1(%r10),%rsi
59	jmp	L$oop8
60.p2align	4
61L$oop8:
62	addb	%al,%cl
63	movl	(%rdi,%rcx,4),%edx
64	movl	%eax,(%rdi,%rcx,4)
65	movl	0(%rdi,%rsi,4),%ebx
66	rorq	$8,%r8
67	movl	%edx,0(%rdi,%r10,4)
68	addb	%al,%dl
69	movb	(%rdi,%rdx,4),%r8b
70	addb	%bl,%cl
71	movl	(%rdi,%rcx,4),%edx
72	movl	%ebx,(%rdi,%rcx,4)
73	movl	4(%rdi,%rsi,4),%eax
74	rorq	$8,%r8
75	movl	%edx,4(%rdi,%r10,4)
76	addb	%bl,%dl
77	movb	(%rdi,%rdx,4),%r8b
78	addb	%al,%cl
79	movl	(%rdi,%rcx,4),%edx
80	movl	%eax,(%rdi,%rcx,4)
81	movl	8(%rdi,%rsi,4),%ebx
82	rorq	$8,%r8
83	movl	%edx,8(%rdi,%r10,4)
84	addb	%al,%dl
85	movb	(%rdi,%rdx,4),%r8b
86	addb	%bl,%cl
87	movl	(%rdi,%rcx,4),%edx
88	movl	%ebx,(%rdi,%rcx,4)
89	movl	12(%rdi,%rsi,4),%eax
90	rorq	$8,%r8
91	movl	%edx,12(%rdi,%r10,4)
92	addb	%bl,%dl
93	movb	(%rdi,%rdx,4),%r8b
94	addb	%al,%cl
95	movl	(%rdi,%rcx,4),%edx
96	movl	%eax,(%rdi,%rcx,4)
97	movl	16(%rdi,%rsi,4),%ebx
98	rorq	$8,%r8
99	movl	%edx,16(%rdi,%r10,4)
100	addb	%al,%dl
101	movb	(%rdi,%rdx,4),%r8b
102	addb	%bl,%cl
103	movl	(%rdi,%rcx,4),%edx
104	movl	%ebx,(%rdi,%rcx,4)
105	movl	20(%rdi,%rsi,4),%eax
106	rorq	$8,%r8
107	movl	%edx,20(%rdi,%r10,4)
108	addb	%bl,%dl
109	movb	(%rdi,%rdx,4),%r8b
110	addb	%al,%cl
111	movl	(%rdi,%rcx,4),%edx
112	movl	%eax,(%rdi,%rcx,4)
113	movl	24(%rdi,%rsi,4),%ebx
114	rorq	$8,%r8
115	movl	%edx,24(%rdi,%r10,4)
116	addb	%al,%dl
117	movb	(%rdi,%rdx,4),%r8b
118	addb	$8,%sil
119	addb	%bl,%cl
120	movl	(%rdi,%rcx,4),%edx
121	movl	%ebx,(%rdi,%rcx,4)
122	movl	-4(%rdi,%rsi,4),%eax
123	rorq	$8,%r8
124	movl	%edx,28(%rdi,%r10,4)
125	addb	%bl,%dl
126	movb	(%rdi,%rdx,4),%r8b
127	addb	$8,%r10b
128	rorq	$8,%r8
129	subq	$8,%r11
130
131	xorq	(%r12),%r8
132	movq	%r8,(%r12,%r13,1)
133	leaq	8(%r12),%r12
134
135	testq	$-8,%r11
136	jnz	L$oop8
137	cmpq	$0,%r11
138	jne	L$loop1
139	jmp	L$exit
140
141.p2align	4
142L$intel:
143	testq	$-32,%r11
144	jz	L$loop1
145	andq	$15,%rbx
146	jz	L$oop16_is_hot
147	subq	%rbx,%r11
148L$oop16_warmup:
149	addb	%al,%cl
150	movl	(%rdi,%rcx,4),%edx
151	movl	%eax,(%rdi,%rcx,4)
152	movl	%edx,(%rdi,%r10,4)
153	addb	%dl,%al
154	incb	%r10b
155	movl	(%rdi,%rax,4),%edx
156	movl	(%rdi,%r10,4),%eax
157	xorb	(%r12),%dl
158	movb	%dl,(%r12,%r13,1)
159	leaq	1(%r12),%r12
160	decq	%rbx
161	jnz	L$oop16_warmup
162
163	movq	%rcx,%rbx
164	xorq	%rcx,%rcx
165	movb	%bl,%cl
166
167L$oop16_is_hot:
168	leaq	(%rdi,%r10,4),%rsi
169	addb	%al,%cl
170	movl	(%rdi,%rcx,4),%edx
171	pxor	%xmm0,%xmm0
172	movl	%eax,(%rdi,%rcx,4)
173	addb	%dl,%al
174	movl	4(%rsi),%ebx
175	movzbl	%al,%eax
176	movl	%edx,0(%rsi)
177	addb	%bl,%cl
178	pinsrw	$0,(%rdi,%rax,4),%xmm0
179	jmp	L$oop16_enter
180.p2align	4
181L$oop16:
182	addb	%al,%cl
183	movl	(%rdi,%rcx,4),%edx
184	pxor	%xmm0,%xmm2
185	psllq	$8,%xmm1
186	pxor	%xmm0,%xmm0
187	movl	%eax,(%rdi,%rcx,4)
188	addb	%dl,%al
189	movl	4(%rsi),%ebx
190	movzbl	%al,%eax
191	movl	%edx,0(%rsi)
192	pxor	%xmm1,%xmm2
193	addb	%bl,%cl
194	pinsrw	$0,(%rdi,%rax,4),%xmm0
195	movdqu	%xmm2,(%r12,%r13,1)
196	leaq	16(%r12),%r12
197L$oop16_enter:
198	movl	(%rdi,%rcx,4),%edx
199	pxor	%xmm1,%xmm1
200	movl	%ebx,(%rdi,%rcx,4)
201	addb	%dl,%bl
202	movl	8(%rsi),%eax
203	movzbl	%bl,%ebx
204	movl	%edx,4(%rsi)
205	addb	%al,%cl
206	pinsrw	$0,(%rdi,%rbx,4),%xmm1
207	movl	(%rdi,%rcx,4),%edx
208	movl	%eax,(%rdi,%rcx,4)
209	addb	%dl,%al
210	movl	12(%rsi),%ebx
211	movzbl	%al,%eax
212	movl	%edx,8(%rsi)
213	addb	%bl,%cl
214	pinsrw	$1,(%rdi,%rax,4),%xmm0
215	movl	(%rdi,%rcx,4),%edx
216	movl	%ebx,(%rdi,%rcx,4)
217	addb	%dl,%bl
218	movl	16(%rsi),%eax
219	movzbl	%bl,%ebx
220	movl	%edx,12(%rsi)
221	addb	%al,%cl
222	pinsrw	$1,(%rdi,%rbx,4),%xmm1
223	movl	(%rdi,%rcx,4),%edx
224	movl	%eax,(%rdi,%rcx,4)
225	addb	%dl,%al
226	movl	20(%rsi),%ebx
227	movzbl	%al,%eax
228	movl	%edx,16(%rsi)
229	addb	%bl,%cl
230	pinsrw	$2,(%rdi,%rax,4),%xmm0
231	movl	(%rdi,%rcx,4),%edx
232	movl	%ebx,(%rdi,%rcx,4)
233	addb	%dl,%bl
234	movl	24(%rsi),%eax
235	movzbl	%bl,%ebx
236	movl	%edx,20(%rsi)
237	addb	%al,%cl
238	pinsrw	$2,(%rdi,%rbx,4),%xmm1
239	movl	(%rdi,%rcx,4),%edx
240	movl	%eax,(%rdi,%rcx,4)
241	addb	%dl,%al
242	movl	28(%rsi),%ebx
243	movzbl	%al,%eax
244	movl	%edx,24(%rsi)
245	addb	%bl,%cl
246	pinsrw	$3,(%rdi,%rax,4),%xmm0
247	movl	(%rdi,%rcx,4),%edx
248	movl	%ebx,(%rdi,%rcx,4)
249	addb	%dl,%bl
250	movl	32(%rsi),%eax
251	movzbl	%bl,%ebx
252	movl	%edx,28(%rsi)
253	addb	%al,%cl
254	pinsrw	$3,(%rdi,%rbx,4),%xmm1
255	movl	(%rdi,%rcx,4),%edx
256	movl	%eax,(%rdi,%rcx,4)
257	addb	%dl,%al
258	movl	36(%rsi),%ebx
259	movzbl	%al,%eax
260	movl	%edx,32(%rsi)
261	addb	%bl,%cl
262	pinsrw	$4,(%rdi,%rax,4),%xmm0
263	movl	(%rdi,%rcx,4),%edx
264	movl	%ebx,(%rdi,%rcx,4)
265	addb	%dl,%bl
266	movl	40(%rsi),%eax
267	movzbl	%bl,%ebx
268	movl	%edx,36(%rsi)
269	addb	%al,%cl
270	pinsrw	$4,(%rdi,%rbx,4),%xmm1
271	movl	(%rdi,%rcx,4),%edx
272	movl	%eax,(%rdi,%rcx,4)
273	addb	%dl,%al
274	movl	44(%rsi),%ebx
275	movzbl	%al,%eax
276	movl	%edx,40(%rsi)
277	addb	%bl,%cl
278	pinsrw	$5,(%rdi,%rax,4),%xmm0
279	movl	(%rdi,%rcx,4),%edx
280	movl	%ebx,(%rdi,%rcx,4)
281	addb	%dl,%bl
282	movl	48(%rsi),%eax
283	movzbl	%bl,%ebx
284	movl	%edx,44(%rsi)
285	addb	%al,%cl
286	pinsrw	$5,(%rdi,%rbx,4),%xmm1
287	movl	(%rdi,%rcx,4),%edx
288	movl	%eax,(%rdi,%rcx,4)
289	addb	%dl,%al
290	movl	52(%rsi),%ebx
291	movzbl	%al,%eax
292	movl	%edx,48(%rsi)
293	addb	%bl,%cl
294	pinsrw	$6,(%rdi,%rax,4),%xmm0
295	movl	(%rdi,%rcx,4),%edx
296	movl	%ebx,(%rdi,%rcx,4)
297	addb	%dl,%bl
298	movl	56(%rsi),%eax
299	movzbl	%bl,%ebx
300	movl	%edx,52(%rsi)
301	addb	%al,%cl
302	pinsrw	$6,(%rdi,%rbx,4),%xmm1
303	movl	(%rdi,%rcx,4),%edx
304	movl	%eax,(%rdi,%rcx,4)
305	addb	%dl,%al
306	movl	60(%rsi),%ebx
307	movzbl	%al,%eax
308	movl	%edx,56(%rsi)
309	addb	%bl,%cl
310	pinsrw	$7,(%rdi,%rax,4),%xmm0
311	addb	$16,%r10b
312	movdqu	(%r12),%xmm2
313	movl	(%rdi,%rcx,4),%edx
314	movl	%ebx,(%rdi,%rcx,4)
315	addb	%dl,%bl
316	movzbl	%bl,%ebx
317	movl	%edx,60(%rsi)
318	leaq	(%rdi,%r10,4),%rsi
319	pinsrw	$7,(%rdi,%rbx,4),%xmm1
320	movl	(%rsi),%eax
321	movq	%rcx,%rbx
322	xorq	%rcx,%rcx
323	subq	$16,%r11
324	movb	%bl,%cl
325	testq	$-16,%r11
326	jnz	L$oop16
327
328	psllq	$8,%xmm1
329	pxor	%xmm0,%xmm2
330	pxor	%xmm1,%xmm2
331	movdqu	%xmm2,(%r12,%r13,1)
332	leaq	16(%r12),%r12
333
334	cmpq	$0,%r11
335	jne	L$loop1
336	jmp	L$exit
337
338.p2align	4
339L$loop1:
340	addb	%al,%cl
341	movl	(%rdi,%rcx,4),%edx
342	movl	%eax,(%rdi,%rcx,4)
343	movl	%edx,(%rdi,%r10,4)
344	addb	%dl,%al
345	incb	%r10b
346	movl	(%rdi,%rax,4),%edx
347	movl	(%rdi,%r10,4),%eax
348	xorb	(%r12),%dl
349	movb	%dl,(%r12,%r13,1)
350	leaq	1(%r12),%r12
351	decq	%r11
352	jnz	L$loop1
353	jmp	L$exit
354
355.p2align	4
356L$RC4_CHAR:
357	addb	$1,%r10b
358	movzbl	(%rdi,%r10,1),%eax
359	testq	$-8,%r11
360	jz	L$cloop1
361	jmp	L$cloop8
362.p2align	4
363L$cloop8:
364	movl	(%r12),%r8d
365	movl	4(%r12),%r9d
366	addb	%al,%cl
367	leaq	1(%r10),%rsi
368	movzbl	(%rdi,%rcx,1),%edx
369	movzbl	%sil,%esi
370	movzbl	(%rdi,%rsi,1),%ebx
371	movb	%al,(%rdi,%rcx,1)
372	cmpq	%rsi,%rcx
373	movb	%dl,(%rdi,%r10,1)
374	jne	L$cmov0
375	movq	%rax,%rbx
376L$cmov0:
377	addb	%al,%dl
378	xorb	(%rdi,%rdx,1),%r8b
379	rorl	$8,%r8d
380	addb	%bl,%cl
381	leaq	1(%rsi),%r10
382	movzbl	(%rdi,%rcx,1),%edx
383	movzbl	%r10b,%r10d
384	movzbl	(%rdi,%r10,1),%eax
385	movb	%bl,(%rdi,%rcx,1)
386	cmpq	%r10,%rcx
387	movb	%dl,(%rdi,%rsi,1)
388	jne	L$cmov1
389	movq	%rbx,%rax
390L$cmov1:
391	addb	%bl,%dl
392	xorb	(%rdi,%rdx,1),%r8b
393	rorl	$8,%r8d
394	addb	%al,%cl
395	leaq	1(%r10),%rsi
396	movzbl	(%rdi,%rcx,1),%edx
397	movzbl	%sil,%esi
398	movzbl	(%rdi,%rsi,1),%ebx
399	movb	%al,(%rdi,%rcx,1)
400	cmpq	%rsi,%rcx
401	movb	%dl,(%rdi,%r10,1)
402	jne	L$cmov2
403	movq	%rax,%rbx
404L$cmov2:
405	addb	%al,%dl
406	xorb	(%rdi,%rdx,1),%r8b
407	rorl	$8,%r8d
408	addb	%bl,%cl
409	leaq	1(%rsi),%r10
410	movzbl	(%rdi,%rcx,1),%edx
411	movzbl	%r10b,%r10d
412	movzbl	(%rdi,%r10,1),%eax
413	movb	%bl,(%rdi,%rcx,1)
414	cmpq	%r10,%rcx
415	movb	%dl,(%rdi,%rsi,1)
416	jne	L$cmov3
417	movq	%rbx,%rax
418L$cmov3:
419	addb	%bl,%dl
420	xorb	(%rdi,%rdx,1),%r8b
421	rorl	$8,%r8d
422	addb	%al,%cl
423	leaq	1(%r10),%rsi
424	movzbl	(%rdi,%rcx,1),%edx
425	movzbl	%sil,%esi
426	movzbl	(%rdi,%rsi,1),%ebx
427	movb	%al,(%rdi,%rcx,1)
428	cmpq	%rsi,%rcx
429	movb	%dl,(%rdi,%r10,1)
430	jne	L$cmov4
431	movq	%rax,%rbx
432L$cmov4:
433	addb	%al,%dl
434	xorb	(%rdi,%rdx,1),%r9b
435	rorl	$8,%r9d
436	addb	%bl,%cl
437	leaq	1(%rsi),%r10
438	movzbl	(%rdi,%rcx,1),%edx
439	movzbl	%r10b,%r10d
440	movzbl	(%rdi,%r10,1),%eax
441	movb	%bl,(%rdi,%rcx,1)
442	cmpq	%r10,%rcx
443	movb	%dl,(%rdi,%rsi,1)
444	jne	L$cmov5
445	movq	%rbx,%rax
446L$cmov5:
447	addb	%bl,%dl
448	xorb	(%rdi,%rdx,1),%r9b
449	rorl	$8,%r9d
450	addb	%al,%cl
451	leaq	1(%r10),%rsi
452	movzbl	(%rdi,%rcx,1),%edx
453	movzbl	%sil,%esi
454	movzbl	(%rdi,%rsi,1),%ebx
455	movb	%al,(%rdi,%rcx,1)
456	cmpq	%rsi,%rcx
457	movb	%dl,(%rdi,%r10,1)
458	jne	L$cmov6
459	movq	%rax,%rbx
460L$cmov6:
461	addb	%al,%dl
462	xorb	(%rdi,%rdx,1),%r9b
463	rorl	$8,%r9d
464	addb	%bl,%cl
465	leaq	1(%rsi),%r10
466	movzbl	(%rdi,%rcx,1),%edx
467	movzbl	%r10b,%r10d
468	movzbl	(%rdi,%r10,1),%eax
469	movb	%bl,(%rdi,%rcx,1)
470	cmpq	%r10,%rcx
471	movb	%dl,(%rdi,%rsi,1)
472	jne	L$cmov7
473	movq	%rbx,%rax
474L$cmov7:
475	addb	%bl,%dl
476	xorb	(%rdi,%rdx,1),%r9b
477	rorl	$8,%r9d
478	leaq	-8(%r11),%r11
479	movl	%r8d,(%r13)
480	leaq	8(%r12),%r12
481	movl	%r9d,4(%r13)
482	leaq	8(%r13),%r13
483
484	testq	$-8,%r11
485	jnz	L$cloop8
486	cmpq	$0,%r11
487	jne	L$cloop1
488	jmp	L$exit
489.p2align	4
490L$cloop1:
491	addb	%al,%cl
492	movzbl	%cl,%ecx
493	movzbl	(%rdi,%rcx,1),%edx
494	movb	%al,(%rdi,%rcx,1)
495	movb	%dl,(%rdi,%r10,1)
496	addb	%al,%dl
497	addb	$1,%r10b
498	movzbl	%dl,%edx
499	movzbl	%r10b,%r10d
500	movzbl	(%rdi,%rdx,1),%edx
501	movzbl	(%rdi,%r10,1),%eax
502	xorb	(%r12),%dl
503	leaq	1(%r12),%r12
504	movb	%dl,(%r13)
505	leaq	1(%r13),%r13
506	subq	$1,%r11
507	jnz	L$cloop1
508	jmp	L$exit
509
510.p2align	4
511L$exit:
512	subb	$1,%r10b
513	movl	%r10d,-8(%rdi)
514	movl	%ecx,-4(%rdi)
515
516	movq	(%rsp),%r13
517	movq	8(%rsp),%r12
518	movq	16(%rsp),%rbx
519	addq	$24,%rsp
520L$epilogue:
521	.byte	0xf3,0xc3
522
523.globl	_asm_RC4_set_key
524.private_extern _asm_RC4_set_key
525
526.p2align	4
527_asm_RC4_set_key:
528	leaq	8(%rdi),%rdi
529	leaq	(%rdx,%rsi,1),%rdx
530	negq	%rsi
531	movq	%rsi,%rcx
532	xorl	%eax,%eax
533	xorq	%r9,%r9
534	xorq	%r10,%r10
535	xorq	%r11,%r11
536
537	movl	_OPENSSL_ia32cap_P(%rip),%r8d
538	btl	$20,%r8d
539	jc	L$c1stloop
540	jmp	L$w1stloop
541
542.p2align	4
543L$w1stloop:
544	movl	%eax,(%rdi,%rax,4)
545	addb	$1,%al
546	jnc	L$w1stloop
547
548	xorq	%r9,%r9
549	xorq	%r8,%r8
550.p2align	4
551L$w2ndloop:
552	movl	(%rdi,%r9,4),%r10d
553	addb	(%rdx,%rsi,1),%r8b
554	addb	%r10b,%r8b
555	addq	$1,%rsi
556	movl	(%rdi,%r8,4),%r11d
557	cmovzq	%rcx,%rsi
558	movl	%r10d,(%rdi,%r8,4)
559	movl	%r11d,(%rdi,%r9,4)
560	addb	$1,%r9b
561	jnc	L$w2ndloop
562	jmp	L$exit_key
563
564.p2align	4
565L$c1stloop:
566	movb	%al,(%rdi,%rax,1)
567	addb	$1,%al
568	jnc	L$c1stloop
569
570	xorq	%r9,%r9
571	xorq	%r8,%r8
572.p2align	4
573L$c2ndloop:
574	movb	(%rdi,%r9,1),%r10b
575	addb	(%rdx,%rsi,1),%r8b
576	addb	%r10b,%r8b
577	addq	$1,%rsi
578	movb	(%rdi,%r8,1),%r11b
579	jnz	L$cnowrap
580	movq	%rcx,%rsi
581L$cnowrap:
582	movb	%r10b,(%rdi,%r8,1)
583	movb	%r11b,(%rdi,%r9,1)
584	addb	$1,%r9b
585	jnc	L$c2ndloop
586	movl	$-1,256(%rdi)
587
588.p2align	4
589L$exit_key:
590	xorl	%eax,%eax
591	movl	%eax,-8(%rdi)
592	movl	%eax,-4(%rdi)
593	.byte	0xf3,0xc3
594
595#endif
596