1#include "x86_arch.h"
2.text
3
4.globl	bn_mul_mont
5.type	bn_mul_mont,@function
6.align	16
7bn_mul_mont:
8	testl	$3,%r9d
9	jnz	.Lmul_enter
10	cmpl	$8,%r9d
11	jb	.Lmul_enter
12	cmpq	%rsi,%rdx
13	jne	.Lmul4x_enter
14	jmp	.Lsqr4x_enter
15
16.align	16
17.Lmul_enter:
18	pushq	%rbx
19	pushq	%rbp
20	pushq	%r12
21	pushq	%r13
22	pushq	%r14
23	pushq	%r15
24
25	movl	%r9d,%r9d
26	leaq	2(%r9),%r10
27	movq	%rsp,%r11
28	negq	%r10
29	leaq	(%rsp,%r10,8),%rsp
30	andq	$-1024,%rsp
31
32	movq	%r11,8(%rsp,%r9,8)
33.Lmul_body:
34	movq	%rdx,%r12
35	movq	(%r8),%r8
36	movq	(%r12),%rbx
37	movq	(%rsi),%rax
38
39	xorq	%r14,%r14
40	xorq	%r15,%r15
41
42	movq	%r8,%rbp
43	mulq	%rbx
44	movq	%rax,%r10
45	movq	(%rcx),%rax
46
47	imulq	%r10,%rbp
48	movq	%rdx,%r11
49
50	mulq	%rbp
51	addq	%rax,%r10
52	movq	8(%rsi),%rax
53	adcq	$0,%rdx
54	movq	%rdx,%r13
55
56	leaq	1(%r15),%r15
57	jmp	.L1st_enter
58
59.align	16
60.L1st:
61	addq	%rax,%r13
62	movq	(%rsi,%r15,8),%rax
63	adcq	$0,%rdx
64	addq	%r11,%r13
65	movq	%r10,%r11
66	adcq	$0,%rdx
67	movq	%r13,-16(%rsp,%r15,8)
68	movq	%rdx,%r13
69
70.L1st_enter:
71	mulq	%rbx
72	addq	%rax,%r11
73	movq	(%rcx,%r15,8),%rax
74	adcq	$0,%rdx
75	leaq	1(%r15),%r15
76	movq	%rdx,%r10
77
78	mulq	%rbp
79	cmpq	%r9,%r15
80	jl	.L1st
81
82	addq	%rax,%r13
83	movq	(%rsi),%rax
84	adcq	$0,%rdx
85	addq	%r11,%r13
86	adcq	$0,%rdx
87	movq	%r13,-16(%rsp,%r15,8)
88	movq	%rdx,%r13
89	movq	%r10,%r11
90
91	xorq	%rdx,%rdx
92	addq	%r11,%r13
93	adcq	$0,%rdx
94	movq	%r13,-8(%rsp,%r9,8)
95	movq	%rdx,(%rsp,%r9,8)
96
97	leaq	1(%r14),%r14
98	jmp	.Louter
99.align	16
100.Louter:
101	movq	(%r12,%r14,8),%rbx
102	xorq	%r15,%r15
103	movq	%r8,%rbp
104	movq	(%rsp),%r10
105	mulq	%rbx
106	addq	%rax,%r10
107	movq	(%rcx),%rax
108	adcq	$0,%rdx
109
110	imulq	%r10,%rbp
111	movq	%rdx,%r11
112
113	mulq	%rbp
114	addq	%rax,%r10
115	movq	8(%rsi),%rax
116	adcq	$0,%rdx
117	movq	8(%rsp),%r10
118	movq	%rdx,%r13
119
120	leaq	1(%r15),%r15
121	jmp	.Linner_enter
122
123.align	16
124.Linner:
125	addq	%rax,%r13
126	movq	(%rsi,%r15,8),%rax
127	adcq	$0,%rdx
128	addq	%r10,%r13
129	movq	(%rsp,%r15,8),%r10
130	adcq	$0,%rdx
131	movq	%r13,-16(%rsp,%r15,8)
132	movq	%rdx,%r13
133
134.Linner_enter:
135	mulq	%rbx
136	addq	%rax,%r11
137	movq	(%rcx,%r15,8),%rax
138	adcq	$0,%rdx
139	addq	%r11,%r10
140	movq	%rdx,%r11
141	adcq	$0,%r11
142	leaq	1(%r15),%r15
143
144	mulq	%rbp
145	cmpq	%r9,%r15
146	jl	.Linner
147
148	addq	%rax,%r13
149	movq	(%rsi),%rax
150	adcq	$0,%rdx
151	addq	%r10,%r13
152	movq	(%rsp,%r15,8),%r10
153	adcq	$0,%rdx
154	movq	%r13,-16(%rsp,%r15,8)
155	movq	%rdx,%r13
156
157	xorq	%rdx,%rdx
158	addq	%r11,%r13
159	adcq	$0,%rdx
160	addq	%r10,%r13
161	adcq	$0,%rdx
162	movq	%r13,-8(%rsp,%r9,8)
163	movq	%rdx,(%rsp,%r9,8)
164
165	leaq	1(%r14),%r14
166	cmpq	%r9,%r14
167	jl	.Louter
168
169	xorq	%r14,%r14
170	movq	(%rsp),%rax
171	leaq	(%rsp),%rsi
172	movq	%r9,%r15
173	jmp	.Lsub
174.align	16
175.Lsub:	sbbq	(%rcx,%r14,8),%rax
176	movq	%rax,(%rdi,%r14,8)
177	movq	8(%rsi,%r14,8),%rax
178	leaq	1(%r14),%r14
179	decq	%r15
180	jnz	.Lsub
181
182	sbbq	$0,%rax
183	xorq	%r14,%r14
184	andq	%rax,%rsi
185	notq	%rax
186	movq	%rdi,%rcx
187	andq	%rax,%rcx
188	movq	%r9,%r15
189	orq	%rcx,%rsi
190.align	16
191.Lcopy:
192	movq	(%rsi,%r14,8),%rax
193	movq	%r14,(%rsp,%r14,8)
194	movq	%rax,(%rdi,%r14,8)
195	leaq	1(%r14),%r14
196	subq	$1,%r15
197	jnz	.Lcopy
198
199	movq	8(%rsp,%r9,8),%rsi
200	movq	$1,%rax
201	movq	(%rsi),%r15
202	movq	8(%rsi),%r14
203	movq	16(%rsi),%r13
204	movq	24(%rsi),%r12
205	movq	32(%rsi),%rbp
206	movq	40(%rsi),%rbx
207	leaq	48(%rsi),%rsp
208.Lmul_epilogue:
209	retq
210.size	bn_mul_mont,.-bn_mul_mont
211.type	bn_mul4x_mont,@function
212.align	16
213bn_mul4x_mont:
214.Lmul4x_enter:
215	pushq	%rbx
216	pushq	%rbp
217	pushq	%r12
218	pushq	%r13
219	pushq	%r14
220	pushq	%r15
221
222	movl	%r9d,%r9d
223	leaq	4(%r9),%r10
224	movq	%rsp,%r11
225	negq	%r10
226	leaq	(%rsp,%r10,8),%rsp
227	andq	$-1024,%rsp
228
229	movq	%r11,8(%rsp,%r9,8)
230.Lmul4x_body:
231	movq	%rdi,16(%rsp,%r9,8)
232	movq	%rdx,%r12
233	movq	(%r8),%r8
234	movq	(%r12),%rbx
235	movq	(%rsi),%rax
236
237	xorq	%r14,%r14
238	xorq	%r15,%r15
239
240	movq	%r8,%rbp
241	mulq	%rbx
242	movq	%rax,%r10
243	movq	(%rcx),%rax
244
245	imulq	%r10,%rbp
246	movq	%rdx,%r11
247
248	mulq	%rbp
249	addq	%rax,%r10
250	movq	8(%rsi),%rax
251	adcq	$0,%rdx
252	movq	%rdx,%rdi
253
254	mulq	%rbx
255	addq	%rax,%r11
256	movq	8(%rcx),%rax
257	adcq	$0,%rdx
258	movq	%rdx,%r10
259
260	mulq	%rbp
261	addq	%rax,%rdi
262	movq	16(%rsi),%rax
263	adcq	$0,%rdx
264	addq	%r11,%rdi
265	leaq	4(%r15),%r15
266	adcq	$0,%rdx
267	movq	%rdi,(%rsp)
268	movq	%rdx,%r13
269	jmp	.L1st4x
270.align	16
271.L1st4x:
272	mulq	%rbx
273	addq	%rax,%r10
274	movq	-16(%rcx,%r15,8),%rax
275	adcq	$0,%rdx
276	movq	%rdx,%r11
277
278	mulq	%rbp
279	addq	%rax,%r13
280	movq	-8(%rsi,%r15,8),%rax
281	adcq	$0,%rdx
282	addq	%r10,%r13
283	adcq	$0,%rdx
284	movq	%r13,-24(%rsp,%r15,8)
285	movq	%rdx,%rdi
286
287	mulq	%rbx
288	addq	%rax,%r11
289	movq	-8(%rcx,%r15,8),%rax
290	adcq	$0,%rdx
291	movq	%rdx,%r10
292
293	mulq	%rbp
294	addq	%rax,%rdi
295	movq	(%rsi,%r15,8),%rax
296	adcq	$0,%rdx
297	addq	%r11,%rdi
298	adcq	$0,%rdx
299	movq	%rdi,-16(%rsp,%r15,8)
300	movq	%rdx,%r13
301
302	mulq	%rbx
303	addq	%rax,%r10
304	movq	(%rcx,%r15,8),%rax
305	adcq	$0,%rdx
306	movq	%rdx,%r11
307
308	mulq	%rbp
309	addq	%rax,%r13
310	movq	8(%rsi,%r15,8),%rax
311	adcq	$0,%rdx
312	addq	%r10,%r13
313	adcq	$0,%rdx
314	movq	%r13,-8(%rsp,%r15,8)
315	movq	%rdx,%rdi
316
317	mulq	%rbx
318	addq	%rax,%r11
319	movq	8(%rcx,%r15,8),%rax
320	adcq	$0,%rdx
321	leaq	4(%r15),%r15
322	movq	%rdx,%r10
323
324	mulq	%rbp
325	addq	%rax,%rdi
326	movq	-16(%rsi,%r15,8),%rax
327	adcq	$0,%rdx
328	addq	%r11,%rdi
329	adcq	$0,%rdx
330	movq	%rdi,-32(%rsp,%r15,8)
331	movq	%rdx,%r13
332	cmpq	%r9,%r15
333	jl	.L1st4x
334
335	mulq	%rbx
336	addq	%rax,%r10
337	movq	-16(%rcx,%r15,8),%rax
338	adcq	$0,%rdx
339	movq	%rdx,%r11
340
341	mulq	%rbp
342	addq	%rax,%r13
343	movq	-8(%rsi,%r15,8),%rax
344	adcq	$0,%rdx
345	addq	%r10,%r13
346	adcq	$0,%rdx
347	movq	%r13,-24(%rsp,%r15,8)
348	movq	%rdx,%rdi
349
350	mulq	%rbx
351	addq	%rax,%r11
352	movq	-8(%rcx,%r15,8),%rax
353	adcq	$0,%rdx
354	movq	%rdx,%r10
355
356	mulq	%rbp
357	addq	%rax,%rdi
358	movq	(%rsi),%rax
359	adcq	$0,%rdx
360	addq	%r11,%rdi
361	adcq	$0,%rdx
362	movq	%rdi,-16(%rsp,%r15,8)
363	movq	%rdx,%r13
364
365	xorq	%rdi,%rdi
366	addq	%r10,%r13
367	adcq	$0,%rdi
368	movq	%r13,-8(%rsp,%r15,8)
369	movq	%rdi,(%rsp,%r15,8)
370
371	leaq	1(%r14),%r14
372.align	4
373.Louter4x:
374	movq	(%r12,%r14,8),%rbx
375	xorq	%r15,%r15
376	movq	(%rsp),%r10
377	movq	%r8,%rbp
378	mulq	%rbx
379	addq	%rax,%r10
380	movq	(%rcx),%rax
381	adcq	$0,%rdx
382
383	imulq	%r10,%rbp
384	movq	%rdx,%r11
385
386	mulq	%rbp
387	addq	%rax,%r10
388	movq	8(%rsi),%rax
389	adcq	$0,%rdx
390	movq	%rdx,%rdi
391
392	mulq	%rbx
393	addq	%rax,%r11
394	movq	8(%rcx),%rax
395	adcq	$0,%rdx
396	addq	8(%rsp),%r11
397	adcq	$0,%rdx
398	movq	%rdx,%r10
399
400	mulq	%rbp
401	addq	%rax,%rdi
402	movq	16(%rsi),%rax
403	adcq	$0,%rdx
404	addq	%r11,%rdi
405	leaq	4(%r15),%r15
406	adcq	$0,%rdx
407	movq	%rdi,(%rsp)
408	movq	%rdx,%r13
409	jmp	.Linner4x
410.align	16
411.Linner4x:
412	mulq	%rbx
413	addq	%rax,%r10
414	movq	-16(%rcx,%r15,8),%rax
415	adcq	$0,%rdx
416	addq	-16(%rsp,%r15,8),%r10
417	adcq	$0,%rdx
418	movq	%rdx,%r11
419
420	mulq	%rbp
421	addq	%rax,%r13
422	movq	-8(%rsi,%r15,8),%rax
423	adcq	$0,%rdx
424	addq	%r10,%r13
425	adcq	$0,%rdx
426	movq	%r13,-24(%rsp,%r15,8)
427	movq	%rdx,%rdi
428
429	mulq	%rbx
430	addq	%rax,%r11
431	movq	-8(%rcx,%r15,8),%rax
432	adcq	$0,%rdx
433	addq	-8(%rsp,%r15,8),%r11
434	adcq	$0,%rdx
435	movq	%rdx,%r10
436
437	mulq	%rbp
438	addq	%rax,%rdi
439	movq	(%rsi,%r15,8),%rax
440	adcq	$0,%rdx
441	addq	%r11,%rdi
442	adcq	$0,%rdx
443	movq	%rdi,-16(%rsp,%r15,8)
444	movq	%rdx,%r13
445
446	mulq	%rbx
447	addq	%rax,%r10
448	movq	(%rcx,%r15,8),%rax
449	adcq	$0,%rdx
450	addq	(%rsp,%r15,8),%r10
451	adcq	$0,%rdx
452	movq	%rdx,%r11
453
454	mulq	%rbp
455	addq	%rax,%r13
456	movq	8(%rsi,%r15,8),%rax
457	adcq	$0,%rdx
458	addq	%r10,%r13
459	adcq	$0,%rdx
460	movq	%r13,-8(%rsp,%r15,8)
461	movq	%rdx,%rdi
462
463	mulq	%rbx
464	addq	%rax,%r11
465	movq	8(%rcx,%r15,8),%rax
466	adcq	$0,%rdx
467	addq	8(%rsp,%r15,8),%r11
468	adcq	$0,%rdx
469	leaq	4(%r15),%r15
470	movq	%rdx,%r10
471
472	mulq	%rbp
473	addq	%rax,%rdi
474	movq	-16(%rsi,%r15,8),%rax
475	adcq	$0,%rdx
476	addq	%r11,%rdi
477	adcq	$0,%rdx
478	movq	%rdi,-32(%rsp,%r15,8)
479	movq	%rdx,%r13
480	cmpq	%r9,%r15
481	jl	.Linner4x
482
483	mulq	%rbx
484	addq	%rax,%r10
485	movq	-16(%rcx,%r15,8),%rax
486	adcq	$0,%rdx
487	addq	-16(%rsp,%r15,8),%r10
488	adcq	$0,%rdx
489	movq	%rdx,%r11
490
491	mulq	%rbp
492	addq	%rax,%r13
493	movq	-8(%rsi,%r15,8),%rax
494	adcq	$0,%rdx
495	addq	%r10,%r13
496	adcq	$0,%rdx
497	movq	%r13,-24(%rsp,%r15,8)
498	movq	%rdx,%rdi
499
500	mulq	%rbx
501	addq	%rax,%r11
502	movq	-8(%rcx,%r15,8),%rax
503	adcq	$0,%rdx
504	addq	-8(%rsp,%r15,8),%r11
505	adcq	$0,%rdx
506	leaq	1(%r14),%r14
507	movq	%rdx,%r10
508
509	mulq	%rbp
510	addq	%rax,%rdi
511	movq	(%rsi),%rax
512	adcq	$0,%rdx
513	addq	%r11,%rdi
514	adcq	$0,%rdx
515	movq	%rdi,-16(%rsp,%r15,8)
516	movq	%rdx,%r13
517
518	xorq	%rdi,%rdi
519	addq	%r10,%r13
520	adcq	$0,%rdi
521	addq	(%rsp,%r9,8),%r13
522	adcq	$0,%rdi
523	movq	%r13,-8(%rsp,%r15,8)
524	movq	%rdi,(%rsp,%r15,8)
525
526	cmpq	%r9,%r14
527	jl	.Louter4x
528	movq	16(%rsp,%r9,8),%rdi
529	movq	0(%rsp),%rax
530	pxor	%xmm0,%xmm0
531	movq	8(%rsp),%rdx
532	shrq	$2,%r9
533	leaq	(%rsp),%rsi
534	xorq	%r14,%r14
535
536	subq	0(%rcx),%rax
537	movq	16(%rsi),%rbx
538	movq	24(%rsi),%rbp
539	sbbq	8(%rcx),%rdx
540	leaq	-1(%r9),%r15
541	jmp	.Lsub4x
542.align	16
543.Lsub4x:
544	movq	%rax,0(%rdi,%r14,8)
545	movq	%rdx,8(%rdi,%r14,8)
546	sbbq	16(%rcx,%r14,8),%rbx
547	movq	32(%rsi,%r14,8),%rax
548	movq	40(%rsi,%r14,8),%rdx
549	sbbq	24(%rcx,%r14,8),%rbp
550	movq	%rbx,16(%rdi,%r14,8)
551	movq	%rbp,24(%rdi,%r14,8)
552	sbbq	32(%rcx,%r14,8),%rax
553	movq	48(%rsi,%r14,8),%rbx
554	movq	56(%rsi,%r14,8),%rbp
555	sbbq	40(%rcx,%r14,8),%rdx
556	leaq	4(%r14),%r14
557	decq	%r15
558	jnz	.Lsub4x
559
560	movq	%rax,0(%rdi,%r14,8)
561	movq	32(%rsi,%r14,8),%rax
562	sbbq	16(%rcx,%r14,8),%rbx
563	movq	%rdx,8(%rdi,%r14,8)
564	sbbq	24(%rcx,%r14,8),%rbp
565	movq	%rbx,16(%rdi,%r14,8)
566
567	sbbq	$0,%rax
568	movq	%rbp,24(%rdi,%r14,8)
569	xorq	%r14,%r14
570	andq	%rax,%rsi
571	notq	%rax
572	movq	%rdi,%rcx
573	andq	%rax,%rcx
574	leaq	-1(%r9),%r15
575	orq	%rcx,%rsi
576
577	movdqu	(%rsi),%xmm1
578	movdqa	%xmm0,(%rsp)
579	movdqu	%xmm1,(%rdi)
580	jmp	.Lcopy4x
581.align	16
582.Lcopy4x:
583	movdqu	16(%rsi,%r14,1),%xmm2
584	movdqu	32(%rsi,%r14,1),%xmm1
585	movdqa	%xmm0,16(%rsp,%r14,1)
586	movdqu	%xmm2,16(%rdi,%r14,1)
587	movdqa	%xmm0,32(%rsp,%r14,1)
588	movdqu	%xmm1,32(%rdi,%r14,1)
589	leaq	32(%r14),%r14
590	decq	%r15
591	jnz	.Lcopy4x
592
593	shlq	$2,%r9
594	movdqu	16(%rsi,%r14,1),%xmm2
595	movdqa	%xmm0,16(%rsp,%r14,1)
596	movdqu	%xmm2,16(%rdi,%r14,1)
597	movq	8(%rsp,%r9,8),%rsi
598	movq	$1,%rax
599	movq	(%rsi),%r15
600	movq	8(%rsi),%r14
601	movq	16(%rsi),%r13
602	movq	24(%rsi),%r12
603	movq	32(%rsi),%rbp
604	movq	40(%rsi),%rbx
605	leaq	48(%rsi),%rsp
606.Lmul4x_epilogue:
607	retq
608.size	bn_mul4x_mont,.-bn_mul4x_mont
609.type	bn_sqr4x_mont,@function
610.align	16
611bn_sqr4x_mont:
612.Lsqr4x_enter:
613	pushq	%rbx
614	pushq	%rbp
615	pushq	%r12
616	pushq	%r13
617	pushq	%r14
618	pushq	%r15
619
620	shll	$3,%r9d
621	xorq	%r10,%r10
622	movq	%rsp,%r11
623	subq	%r9,%r10
624	movq	(%r8),%r8
625	leaq	-72(%rsp,%r10,2),%rsp
626	andq	$-1024,%rsp
627
628
629
630
631
632
633
634
635
636
637
638	movq	%rdi,32(%rsp)
639	movq	%rcx,40(%rsp)
640	movq	%r8,48(%rsp)
641	movq	%r11,56(%rsp)
642.Lsqr4x_body:
643
644
645
646
647
648
649
650	leaq	32(%r10),%rbp
651	leaq	(%rsi,%r9,1),%rsi
652
653	movq	%r9,%rcx
654
655
656	movq	-32(%rsi,%rbp,1),%r14
657	leaq	64(%rsp,%r9,2),%rdi
658	movq	-24(%rsi,%rbp,1),%rax
659	leaq	-32(%rdi,%rbp,1),%rdi
660	movq	-16(%rsi,%rbp,1),%rbx
661	movq	%rax,%r15
662
663	mulq	%r14
664	movq	%rax,%r10
665	movq	%rbx,%rax
666	movq	%rdx,%r11
667	movq	%r10,-24(%rdi,%rbp,1)
668
669	xorq	%r10,%r10
670	mulq	%r14
671	addq	%rax,%r11
672	movq	%rbx,%rax
673	adcq	%rdx,%r10
674	movq	%r11,-16(%rdi,%rbp,1)
675
676	leaq	-16(%rbp),%rcx
677
678
679	movq	8(%rsi,%rcx,1),%rbx
680	mulq	%r15
681	movq	%rax,%r12
682	movq	%rbx,%rax
683	movq	%rdx,%r13
684
685	xorq	%r11,%r11
686	addq	%r12,%r10
687	leaq	16(%rcx),%rcx
688	adcq	$0,%r11
689	mulq	%r14
690	addq	%rax,%r10
691	movq	%rbx,%rax
692	adcq	%rdx,%r11
693	movq	%r10,-8(%rdi,%rcx,1)
694	jmp	.Lsqr4x_1st
695
696.align	16
697.Lsqr4x_1st:
698	movq	(%rsi,%rcx,1),%rbx
699	xorq	%r12,%r12
700	mulq	%r15
701	addq	%rax,%r13
702	movq	%rbx,%rax
703	adcq	%rdx,%r12
704
705	xorq	%r10,%r10
706	addq	%r13,%r11
707	adcq	$0,%r10
708	mulq	%r14
709	addq	%rax,%r11
710	movq	%rbx,%rax
711	adcq	%rdx,%r10
712	movq	%r11,(%rdi,%rcx,1)
713
714
715	movq	8(%rsi,%rcx,1),%rbx
716	xorq	%r13,%r13
717	mulq	%r15
718	addq	%rax,%r12
719	movq	%rbx,%rax
720	adcq	%rdx,%r13
721
722	xorq	%r11,%r11
723	addq	%r12,%r10
724	adcq	$0,%r11
725	mulq	%r14
726	addq	%rax,%r10
727	movq	%rbx,%rax
728	adcq	%rdx,%r11
729	movq	%r10,8(%rdi,%rcx,1)
730
731	movq	16(%rsi,%rcx,1),%rbx
732	xorq	%r12,%r12
733	mulq	%r15
734	addq	%rax,%r13
735	movq	%rbx,%rax
736	adcq	%rdx,%r12
737
738	xorq	%r10,%r10
739	addq	%r13,%r11
740	adcq	$0,%r10
741	mulq	%r14
742	addq	%rax,%r11
743	movq	%rbx,%rax
744	adcq	%rdx,%r10
745	movq	%r11,16(%rdi,%rcx,1)
746
747
748	movq	24(%rsi,%rcx,1),%rbx
749	xorq	%r13,%r13
750	mulq	%r15
751	addq	%rax,%r12
752	movq	%rbx,%rax
753	adcq	%rdx,%r13
754
755	xorq	%r11,%r11
756	addq	%r12,%r10
757	leaq	32(%rcx),%rcx
758	adcq	$0,%r11
759	mulq	%r14
760	addq	%rax,%r10
761	movq	%rbx,%rax
762	adcq	%rdx,%r11
763	movq	%r10,-8(%rdi,%rcx,1)
764
765	cmpq	$0,%rcx
766	jne	.Lsqr4x_1st
767
768	xorq	%r12,%r12
769	addq	%r11,%r13
770	adcq	$0,%r12
771	mulq	%r15
772	addq	%rax,%r13
773	adcq	%rdx,%r12
774
775	movq	%r13,(%rdi)
776	leaq	16(%rbp),%rbp
777	movq	%r12,8(%rdi)
778	jmp	.Lsqr4x_outer
779
780.align	16
781.Lsqr4x_outer:
782	movq	-32(%rsi,%rbp,1),%r14
783	leaq	64(%rsp,%r9,2),%rdi
784	movq	-24(%rsi,%rbp,1),%rax
785	leaq	-32(%rdi,%rbp,1),%rdi
786	movq	-16(%rsi,%rbp,1),%rbx
787	movq	%rax,%r15
788
789	movq	-24(%rdi,%rbp,1),%r10
790	xorq	%r11,%r11
791	mulq	%r14
792	addq	%rax,%r10
793	movq	%rbx,%rax
794	adcq	%rdx,%r11
795	movq	%r10,-24(%rdi,%rbp,1)
796
797	xorq	%r10,%r10
798	addq	-16(%rdi,%rbp,1),%r11
799	adcq	$0,%r10
800	mulq	%r14
801	addq	%rax,%r11
802	movq	%rbx,%rax
803	adcq	%rdx,%r10
804	movq	%r11,-16(%rdi,%rbp,1)
805
806	leaq	-16(%rbp),%rcx
807	xorq	%r12,%r12
808
809
810	movq	8(%rsi,%rcx,1),%rbx
811	xorq	%r13,%r13
812	addq	8(%rdi,%rcx,1),%r12
813	adcq	$0,%r13
814	mulq	%r15
815	addq	%rax,%r12
816	movq	%rbx,%rax
817	adcq	%rdx,%r13
818
819	xorq	%r11,%r11
820	addq	%r12,%r10
821	adcq	$0,%r11
822	mulq	%r14
823	addq	%rax,%r10
824	movq	%rbx,%rax
825	adcq	%rdx,%r11
826	movq	%r10,8(%rdi,%rcx,1)
827
828	leaq	16(%rcx),%rcx
829	jmp	.Lsqr4x_inner
830
831.align	16
832.Lsqr4x_inner:
833	movq	(%rsi,%rcx,1),%rbx
834	xorq	%r12,%r12
835	addq	(%rdi,%rcx,1),%r13
836	adcq	$0,%r12
837	mulq	%r15
838	addq	%rax,%r13
839	movq	%rbx,%rax
840	adcq	%rdx,%r12
841
842	xorq	%r10,%r10
843	addq	%r13,%r11
844	adcq	$0,%r10
845	mulq	%r14
846	addq	%rax,%r11
847	movq	%rbx,%rax
848	adcq	%rdx,%r10
849	movq	%r11,(%rdi,%rcx,1)
850
851	movq	8(%rsi,%rcx,1),%rbx
852	xorq	%r13,%r13
853	addq	8(%rdi,%rcx,1),%r12
854	adcq	$0,%r13
855	mulq	%r15
856	addq	%rax,%r12
857	movq	%rbx,%rax
858	adcq	%rdx,%r13
859
860	xorq	%r11,%r11
861	addq	%r12,%r10
862	leaq	16(%rcx),%rcx
863	adcq	$0,%r11
864	mulq	%r14
865	addq	%rax,%r10
866	movq	%rbx,%rax
867	adcq	%rdx,%r11
868	movq	%r10,-8(%rdi,%rcx,1)
869
870	cmpq	$0,%rcx
871	jne	.Lsqr4x_inner
872
873	xorq	%r12,%r12
874	addq	%r11,%r13
875	adcq	$0,%r12
876	mulq	%r15
877	addq	%rax,%r13
878	adcq	%rdx,%r12
879
880	movq	%r13,(%rdi)
881	movq	%r12,8(%rdi)
882
883	addq	$16,%rbp
884	jnz	.Lsqr4x_outer
885
886
887	movq	-32(%rsi),%r14
888	leaq	64(%rsp,%r9,2),%rdi
889	movq	-24(%rsi),%rax
890	leaq	-32(%rdi,%rbp,1),%rdi
891	movq	-16(%rsi),%rbx
892	movq	%rax,%r15
893
894	xorq	%r11,%r11
895	mulq	%r14
896	addq	%rax,%r10
897	movq	%rbx,%rax
898	adcq	%rdx,%r11
899	movq	%r10,-24(%rdi)
900
901	xorq	%r10,%r10
902	addq	%r13,%r11
903	adcq	$0,%r10
904	mulq	%r14
905	addq	%rax,%r11
906	movq	%rbx,%rax
907	adcq	%rdx,%r10
908	movq	%r11,-16(%rdi)
909
910	movq	-8(%rsi),%rbx
911	mulq	%r15
912	addq	%rax,%r12
913	movq	%rbx,%rax
914	adcq	$0,%rdx
915
916	xorq	%r11,%r11
917	addq	%r12,%r10
918	movq	%rdx,%r13
919	adcq	$0,%r11
920	mulq	%r14
921	addq	%rax,%r10
922	movq	%rbx,%rax
923	adcq	%rdx,%r11
924	movq	%r10,-8(%rdi)
925
926	xorq	%r12,%r12
927	addq	%r11,%r13
928	adcq	$0,%r12
929	mulq	%r15
930	addq	%rax,%r13
931	movq	-16(%rsi),%rax
932	adcq	%rdx,%r12
933
934	movq	%r13,(%rdi)
935	movq	%r12,8(%rdi)
936
937	mulq	%rbx
938	addq	$16,%rbp
939	xorq	%r14,%r14
940	subq	%r9,%rbp
941	xorq	%r15,%r15
942
943	addq	%r12,%rax
944	adcq	$0,%rdx
945	movq	%rax,8(%rdi)
946	movq	%rdx,16(%rdi)
947	movq	%r15,24(%rdi)
948
949	movq	-16(%rsi,%rbp,1),%rax
950	leaq	64(%rsp,%r9,2),%rdi
951	xorq	%r10,%r10
952	movq	-24(%rdi,%rbp,2),%r11
953
954	leaq	(%r14,%r10,2),%r12
955	shrq	$63,%r10
956	leaq	(%rcx,%r11,2),%r13
957	shrq	$63,%r11
958	orq	%r10,%r13
959	movq	-16(%rdi,%rbp,2),%r10
960	movq	%r11,%r14
961	mulq	%rax
962	negq	%r15
963	movq	-8(%rdi,%rbp,2),%r11
964	adcq	%rax,%r12
965	movq	-8(%rsi,%rbp,1),%rax
966	movq	%r12,-32(%rdi,%rbp,2)
967	adcq	%rdx,%r13
968
969	leaq	(%r14,%r10,2),%rbx
970	movq	%r13,-24(%rdi,%rbp,2)
971	sbbq	%r15,%r15
972	shrq	$63,%r10
973	leaq	(%rcx,%r11,2),%r8
974	shrq	$63,%r11
975	orq	%r10,%r8
976	movq	0(%rdi,%rbp,2),%r10
977	movq	%r11,%r14
978	mulq	%rax
979	negq	%r15
980	movq	8(%rdi,%rbp,2),%r11
981	adcq	%rax,%rbx
982	movq	0(%rsi,%rbp,1),%rax
983	movq	%rbx,-16(%rdi,%rbp,2)
984	adcq	%rdx,%r8
985	leaq	16(%rbp),%rbp
986	movq	%r8,-40(%rdi,%rbp,2)
987	sbbq	%r15,%r15
988	jmp	.Lsqr4x_shift_n_add
989
990.align	16
991.Lsqr4x_shift_n_add:
992	leaq	(%r14,%r10,2),%r12
993	shrq	$63,%r10
994	leaq	(%rcx,%r11,2),%r13
995	shrq	$63,%r11
996	orq	%r10,%r13
997	movq	-16(%rdi,%rbp,2),%r10
998	movq	%r11,%r14
999	mulq	%rax
1000	negq	%r15
1001	movq	-8(%rdi,%rbp,2),%r11
1002	adcq	%rax,%r12
1003	movq	-8(%rsi,%rbp,1),%rax
1004	movq	%r12,-32(%rdi,%rbp,2)
1005	adcq	%rdx,%r13
1006
1007	leaq	(%r14,%r10,2),%rbx
1008	movq	%r13,-24(%rdi,%rbp,2)
1009	sbbq	%r15,%r15
1010	shrq	$63,%r10
1011	leaq	(%rcx,%r11,2),%r8
1012	shrq	$63,%r11
1013	orq	%r10,%r8
1014	movq	0(%rdi,%rbp,2),%r10
1015	movq	%r11,%r14
1016	mulq	%rax
1017	negq	%r15
1018	movq	8(%rdi,%rbp,2),%r11
1019	adcq	%rax,%rbx
1020	movq	0(%rsi,%rbp,1),%rax
1021	movq	%rbx,-16(%rdi,%rbp,2)
1022	adcq	%rdx,%r8
1023
1024	leaq	(%r14,%r10,2),%r12
1025	movq	%r8,-8(%rdi,%rbp,2)
1026	sbbq	%r15,%r15
1027	shrq	$63,%r10
1028	leaq	(%rcx,%r11,2),%r13
1029	shrq	$63,%r11
1030	orq	%r10,%r13
1031	movq	16(%rdi,%rbp,2),%r10
1032	movq	%r11,%r14
1033	mulq	%rax
1034	negq	%r15
1035	movq	24(%rdi,%rbp,2),%r11
1036	adcq	%rax,%r12
1037	movq	8(%rsi,%rbp,1),%rax
1038	movq	%r12,0(%rdi,%rbp,2)
1039	adcq	%rdx,%r13
1040
1041	leaq	(%r14,%r10,2),%rbx
1042	movq	%r13,8(%rdi,%rbp,2)
1043	sbbq	%r15,%r15
1044	shrq	$63,%r10
1045	leaq	(%rcx,%r11,2),%r8
1046	shrq	$63,%r11
1047	orq	%r10,%r8
1048	movq	32(%rdi,%rbp,2),%r10
1049	movq	%r11,%r14
1050	mulq	%rax
1051	negq	%r15
1052	movq	40(%rdi,%rbp,2),%r11
1053	adcq	%rax,%rbx
1054	movq	16(%rsi,%rbp,1),%rax
1055	movq	%rbx,16(%rdi,%rbp,2)
1056	adcq	%rdx,%r8
1057	movq	%r8,24(%rdi,%rbp,2)
1058	sbbq	%r15,%r15
1059	addq	$32,%rbp
1060	jnz	.Lsqr4x_shift_n_add
1061
1062	leaq	(%r14,%r10,2),%r12
1063	shrq	$63,%r10
1064	leaq	(%rcx,%r11,2),%r13
1065	shrq	$63,%r11
1066	orq	%r10,%r13
1067	movq	-16(%rdi),%r10
1068	movq	%r11,%r14
1069	mulq	%rax
1070	negq	%r15
1071	movq	-8(%rdi),%r11
1072	adcq	%rax,%r12
1073	movq	-8(%rsi),%rax
1074	movq	%r12,-32(%rdi)
1075	adcq	%rdx,%r13
1076
1077	leaq	(%r14,%r10,2),%rbx
1078	movq	%r13,-24(%rdi)
1079	sbbq	%r15,%r15
1080	shrq	$63,%r10
1081	leaq	(%rcx,%r11,2),%r8
1082	shrq	$63,%r11
1083	orq	%r10,%r8
1084	mulq	%rax
1085	negq	%r15
1086	adcq	%rax,%rbx
1087	adcq	%rdx,%r8
1088	movq	%rbx,-16(%rdi)
1089	movq	%r8,-8(%rdi)
1090	movq	40(%rsp),%rsi
1091	movq	48(%rsp),%r8
1092	xorq	%rcx,%rcx
1093	movq	%r9,0(%rsp)
1094	subq	%r9,%rcx
1095	movq	64(%rsp),%r10
1096	movq	%r8,%r14
1097	leaq	64(%rsp,%r9,2),%rax
1098	leaq	64(%rsp,%r9,1),%rdi
1099	movq	%rax,8(%rsp)
1100	leaq	(%rsi,%r9,1),%rsi
1101	xorq	%rbp,%rbp
1102
1103	movq	0(%rsi,%rcx,1),%rax
1104	movq	8(%rsi,%rcx,1),%r9
1105	imulq	%r10,%r14
1106	movq	%rax,%rbx
1107	jmp	.Lsqr4x_mont_outer
1108
1109.align	16
1110.Lsqr4x_mont_outer:
1111	xorq	%r11,%r11
1112	mulq	%r14
1113	addq	%rax,%r10
1114	movq	%r9,%rax
1115	adcq	%rdx,%r11
1116	movq	%r8,%r15
1117
1118	xorq	%r10,%r10
1119	addq	8(%rdi,%rcx,1),%r11
1120	adcq	$0,%r10
1121	mulq	%r14
1122	addq	%rax,%r11
1123	movq	%rbx,%rax
1124	adcq	%rdx,%r10
1125
1126	imulq	%r11,%r15
1127
1128	movq	16(%rsi,%rcx,1),%rbx
1129	xorq	%r13,%r13
1130	addq	%r11,%r12
1131	adcq	$0,%r13
1132	mulq	%r15
1133	addq	%rax,%r12
1134	movq	%rbx,%rax
1135	adcq	%rdx,%r13
1136	movq	%r12,8(%rdi,%rcx,1)
1137
1138	xorq	%r11,%r11
1139	addq	16(%rdi,%rcx,1),%r10
1140	adcq	$0,%r11
1141	mulq	%r14
1142	addq	%rax,%r10
1143	movq	%r9,%rax
1144	adcq	%rdx,%r11
1145
1146	movq	24(%rsi,%rcx,1),%r9
1147	xorq	%r12,%r12
1148	addq	%r10,%r13
1149	adcq	$0,%r12
1150	mulq	%r15
1151	addq	%rax,%r13
1152	movq	%r9,%rax
1153	adcq	%rdx,%r12
1154	movq	%r13,16(%rdi,%rcx,1)
1155
1156	xorq	%r10,%r10
1157	addq	24(%rdi,%rcx,1),%r11
1158	leaq	32(%rcx),%rcx
1159	adcq	$0,%r10
1160	mulq	%r14
1161	addq	%rax,%r11
1162	movq	%rbx,%rax
1163	adcq	%rdx,%r10
1164	jmp	.Lsqr4x_mont_inner
1165
1166.align	16
1167.Lsqr4x_mont_inner:
1168	movq	(%rsi,%rcx,1),%rbx
1169	xorq	%r13,%r13
1170	addq	%r11,%r12
1171	adcq	$0,%r13
1172	mulq	%r15
1173	addq	%rax,%r12
1174	movq	%rbx,%rax
1175	adcq	%rdx,%r13
1176	movq	%r12,-8(%rdi,%rcx,1)
1177
1178	xorq	%r11,%r11
1179	addq	(%rdi,%rcx,1),%r10
1180	adcq	$0,%r11
1181	mulq	%r14
1182	addq	%rax,%r10
1183	movq	%r9,%rax
1184	adcq	%rdx,%r11
1185
1186	movq	8(%rsi,%rcx,1),%r9
1187	xorq	%r12,%r12
1188	addq	%r10,%r13
1189	adcq	$0,%r12
1190	mulq	%r15
1191	addq	%rax,%r13
1192	movq	%r9,%rax
1193	adcq	%rdx,%r12
1194	movq	%r13,(%rdi,%rcx,1)
1195
1196	xorq	%r10,%r10
1197	addq	8(%rdi,%rcx,1),%r11
1198	adcq	$0,%r10
1199	mulq	%r14
1200	addq	%rax,%r11
1201	movq	%rbx,%rax
1202	adcq	%rdx,%r10
1203
1204
1205	movq	16(%rsi,%rcx,1),%rbx
1206	xorq	%r13,%r13
1207	addq	%r11,%r12
1208	adcq	$0,%r13
1209	mulq	%r15
1210	addq	%rax,%r12
1211	movq	%rbx,%rax
1212	adcq	%rdx,%r13
1213	movq	%r12,8(%rdi,%rcx,1)
1214
1215	xorq	%r11,%r11
1216	addq	16(%rdi,%rcx,1),%r10
1217	adcq	$0,%r11
1218	mulq	%r14
1219	addq	%rax,%r10
1220	movq	%r9,%rax
1221	adcq	%rdx,%r11
1222
1223	movq	24(%rsi,%rcx,1),%r9
1224	xorq	%r12,%r12
1225	addq	%r10,%r13
1226	adcq	$0,%r12
1227	mulq	%r15
1228	addq	%rax,%r13
1229	movq	%r9,%rax
1230	adcq	%rdx,%r12
1231	movq	%r13,16(%rdi,%rcx,1)
1232
1233	xorq	%r10,%r10
1234	addq	24(%rdi,%rcx,1),%r11
1235	leaq	32(%rcx),%rcx
1236	adcq	$0,%r10
1237	mulq	%r14
1238	addq	%rax,%r11
1239	movq	%rbx,%rax
1240	adcq	%rdx,%r10
1241	cmpq	$0,%rcx
1242	jne	.Lsqr4x_mont_inner
1243
1244	subq	0(%rsp),%rcx
1245	movq	%r8,%r14
1246
1247	xorq	%r13,%r13
1248	addq	%r11,%r12
1249	adcq	$0,%r13
1250	mulq	%r15
1251	addq	%rax,%r12
1252	movq	%r9,%rax
1253	adcq	%rdx,%r13
1254	movq	%r12,-8(%rdi)
1255
1256	xorq	%r11,%r11
1257	addq	(%rdi),%r10
1258	adcq	$0,%r11
1259	movq	0(%rsi,%rcx,1),%rbx
1260	addq	%rbp,%r10
1261	adcq	$0,%r11
1262
1263	imulq	16(%rdi,%rcx,1),%r14
1264	xorq	%r12,%r12
1265	movq	8(%rsi,%rcx,1),%r9
1266	addq	%r10,%r13
1267	movq	16(%rdi,%rcx,1),%r10
1268	adcq	$0,%r12
1269	mulq	%r15
1270	addq	%rax,%r13
1271	movq	%rbx,%rax
1272	adcq	%rdx,%r12
1273	movq	%r13,(%rdi)
1274
1275	xorq	%rbp,%rbp
1276	addq	8(%rdi),%r12
1277	adcq	%rbp,%rbp
1278	addq	%r11,%r12
1279	leaq	16(%rdi),%rdi
1280	adcq	$0,%rbp
1281	movq	%r12,-8(%rdi)
1282	cmpq	8(%rsp),%rdi
1283	jb	.Lsqr4x_mont_outer
1284
1285	movq	0(%rsp),%r9
1286	movq	%rbp,(%rdi)
1287	movq	64(%rsp,%r9,1),%rax
1288	leaq	64(%rsp,%r9,1),%rbx
1289	movq	40(%rsp),%rsi
1290	shrq	$5,%r9
1291	movq	8(%rbx),%rdx
1292	xorq	%rbp,%rbp
1293
1294	movq	32(%rsp),%rdi
1295	subq	0(%rsi),%rax
1296	movq	16(%rbx),%r10
1297	movq	24(%rbx),%r11
1298	sbbq	8(%rsi),%rdx
1299	leaq	-1(%r9),%rcx
1300	jmp	.Lsqr4x_sub
1301.align	16
1302.Lsqr4x_sub:
1303	movq	%rax,0(%rdi,%rbp,8)
1304	movq	%rdx,8(%rdi,%rbp,8)
1305	sbbq	16(%rsi,%rbp,8),%r10
1306	movq	32(%rbx,%rbp,8),%rax
1307	movq	40(%rbx,%rbp,8),%rdx
1308	sbbq	24(%rsi,%rbp,8),%r11
1309	movq	%r10,16(%rdi,%rbp,8)
1310	movq	%r11,24(%rdi,%rbp,8)
1311	sbbq	32(%rsi,%rbp,8),%rax
1312	movq	48(%rbx,%rbp,8),%r10
1313	movq	56(%rbx,%rbp,8),%r11
1314	sbbq	40(%rsi,%rbp,8),%rdx
1315	leaq	4(%rbp),%rbp
1316	decq	%rcx
1317	jnz	.Lsqr4x_sub
1318
1319	movq	%rax,0(%rdi,%rbp,8)
1320	movq	32(%rbx,%rbp,8),%rax
1321	sbbq	16(%rsi,%rbp,8),%r10
1322	movq	%rdx,8(%rdi,%rbp,8)
1323	sbbq	24(%rsi,%rbp,8),%r11
1324	movq	%r10,16(%rdi,%rbp,8)
1325
1326	sbbq	$0,%rax
1327	movq	%r11,24(%rdi,%rbp,8)
1328	xorq	%rbp,%rbp
1329	andq	%rax,%rbx
1330	notq	%rax
1331	movq	%rdi,%rsi
1332	andq	%rax,%rsi
1333	leaq	-1(%r9),%rcx
1334	orq	%rsi,%rbx
1335
1336	pxor	%xmm0,%xmm0
1337	leaq	64(%rsp,%r9,8),%rsi
1338	movdqu	(%rbx),%xmm1
1339	leaq	(%rsi,%r9,8),%rsi
1340	movdqa	%xmm0,64(%rsp)
1341	movdqa	%xmm0,(%rsi)
1342	movdqu	%xmm1,(%rdi)
1343	jmp	.Lsqr4x_copy
1344.align	16
1345.Lsqr4x_copy:
1346	movdqu	16(%rbx,%rbp,1),%xmm2
1347	movdqu	32(%rbx,%rbp,1),%xmm1
1348	movdqa	%xmm0,80(%rsp,%rbp,1)
1349	movdqa	%xmm0,96(%rsp,%rbp,1)
1350	movdqa	%xmm0,16(%rsi,%rbp,1)
1351	movdqa	%xmm0,32(%rsi,%rbp,1)
1352	movdqu	%xmm2,16(%rdi,%rbp,1)
1353	movdqu	%xmm1,32(%rdi,%rbp,1)
1354	leaq	32(%rbp),%rbp
1355	decq	%rcx
1356	jnz	.Lsqr4x_copy
1357
1358	movdqu	16(%rbx,%rbp,1),%xmm2
1359	movdqa	%xmm0,80(%rsp,%rbp,1)
1360	movdqa	%xmm0,16(%rsi,%rbp,1)
1361	movdqu	%xmm2,16(%rdi,%rbp,1)
1362	movq	56(%rsp),%rsi
1363	movq	$1,%rax
1364	movq	0(%rsi),%r15
1365	movq	8(%rsi),%r14
1366	movq	16(%rsi),%r13
1367	movq	24(%rsi),%r12
1368	movq	32(%rsi),%rbp
1369	movq	40(%rsi),%rbx
1370	leaq	48(%rsi),%rsp
1371.Lsqr4x_epilogue:
1372	retq
1373.size	bn_sqr4x_mont,.-bn_sqr4x_mont
1374.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
1375.align	16
1376#if defined(HAVE_GNU_STACK)
1377.section .note.GNU-stack,"",%progbits
1378#endif
1379