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