1default	rel
2%define XMMWORD
3%define YMMWORD
4%define ZMMWORD
5section	.text code align=64
6
7
8global	rsaz_1024_sqr_avx2
9
10ALIGN	64
11rsaz_1024_sqr_avx2:
12	mov	QWORD[8+rsp],rdi	;WIN64 prologue
13	mov	QWORD[16+rsp],rsi
14	mov	rax,rsp
15$L$SEH_begin_rsaz_1024_sqr_avx2:
16	mov	rdi,rcx
17	mov	rsi,rdx
18	mov	rdx,r8
19	mov	rcx,r9
20	mov	r8,QWORD[40+rsp]
21
22
23
24	lea	rax,[rsp]
25
26	push	rbx
27
28	push	rbp
29
30	push	r12
31
32	push	r13
33
34	push	r14
35
36	push	r15
37
38	vzeroupper
39	lea	rsp,[((-168))+rsp]
40	vmovaps	XMMWORD[(-216)+rax],xmm6
41	vmovaps	XMMWORD[(-200)+rax],xmm7
42	vmovaps	XMMWORD[(-184)+rax],xmm8
43	vmovaps	XMMWORD[(-168)+rax],xmm9
44	vmovaps	XMMWORD[(-152)+rax],xmm10
45	vmovaps	XMMWORD[(-136)+rax],xmm11
46	vmovaps	XMMWORD[(-120)+rax],xmm12
47	vmovaps	XMMWORD[(-104)+rax],xmm13
48	vmovaps	XMMWORD[(-88)+rax],xmm14
49	vmovaps	XMMWORD[(-72)+rax],xmm15
50$L$sqr_1024_body:
51	mov	rbp,rax
52
53	mov	r13,rdx
54	sub	rsp,832
55	mov	r15,r13
56	sub	rdi,-128
57	sub	rsi,-128
58	sub	r13,-128
59
60	and	r15,4095
61	add	r15,32*10
62	shr	r15,12
63	vpxor	ymm9,ymm9,ymm9
64	jz	NEAR $L$sqr_1024_no_n_copy
65
66
67
68
69
70	sub	rsp,32*10
71	vmovdqu	ymm0,YMMWORD[((0-128))+r13]
72	and	rsp,-2048
73	vmovdqu	ymm1,YMMWORD[((32-128))+r13]
74	vmovdqu	ymm2,YMMWORD[((64-128))+r13]
75	vmovdqu	ymm3,YMMWORD[((96-128))+r13]
76	vmovdqu	ymm4,YMMWORD[((128-128))+r13]
77	vmovdqu	ymm5,YMMWORD[((160-128))+r13]
78	vmovdqu	ymm6,YMMWORD[((192-128))+r13]
79	vmovdqu	ymm7,YMMWORD[((224-128))+r13]
80	vmovdqu	ymm8,YMMWORD[((256-128))+r13]
81	lea	r13,[((832+128))+rsp]
82	vmovdqu	YMMWORD[(0-128)+r13],ymm0
83	vmovdqu	YMMWORD[(32-128)+r13],ymm1
84	vmovdqu	YMMWORD[(64-128)+r13],ymm2
85	vmovdqu	YMMWORD[(96-128)+r13],ymm3
86	vmovdqu	YMMWORD[(128-128)+r13],ymm4
87	vmovdqu	YMMWORD[(160-128)+r13],ymm5
88	vmovdqu	YMMWORD[(192-128)+r13],ymm6
89	vmovdqu	YMMWORD[(224-128)+r13],ymm7
90	vmovdqu	YMMWORD[(256-128)+r13],ymm8
91	vmovdqu	YMMWORD[(288-128)+r13],ymm9
92
93$L$sqr_1024_no_n_copy:
94	and	rsp,-1024
95
96	vmovdqu	ymm1,YMMWORD[((32-128))+rsi]
97	vmovdqu	ymm2,YMMWORD[((64-128))+rsi]
98	vmovdqu	ymm3,YMMWORD[((96-128))+rsi]
99	vmovdqu	ymm4,YMMWORD[((128-128))+rsi]
100	vmovdqu	ymm5,YMMWORD[((160-128))+rsi]
101	vmovdqu	ymm6,YMMWORD[((192-128))+rsi]
102	vmovdqu	ymm7,YMMWORD[((224-128))+rsi]
103	vmovdqu	ymm8,YMMWORD[((256-128))+rsi]
104
105	lea	rbx,[192+rsp]
106	vmovdqu	ymm15,YMMWORD[$L$and_mask]
107	jmp	NEAR $L$OOP_GRANDE_SQR_1024
108
109ALIGN	32
110$L$OOP_GRANDE_SQR_1024:
111	lea	r9,[((576+128))+rsp]
112	lea	r12,[448+rsp]
113
114
115
116
117	vpaddq	ymm1,ymm1,ymm1
118	vpbroadcastq	ymm10,QWORD[((0-128))+rsi]
119	vpaddq	ymm2,ymm2,ymm2
120	vmovdqa	YMMWORD[(0-128)+r9],ymm1
121	vpaddq	ymm3,ymm3,ymm3
122	vmovdqa	YMMWORD[(32-128)+r9],ymm2
123	vpaddq	ymm4,ymm4,ymm4
124	vmovdqa	YMMWORD[(64-128)+r9],ymm3
125	vpaddq	ymm5,ymm5,ymm5
126	vmovdqa	YMMWORD[(96-128)+r9],ymm4
127	vpaddq	ymm6,ymm6,ymm6
128	vmovdqa	YMMWORD[(128-128)+r9],ymm5
129	vpaddq	ymm7,ymm7,ymm7
130	vmovdqa	YMMWORD[(160-128)+r9],ymm6
131	vpaddq	ymm8,ymm8,ymm8
132	vmovdqa	YMMWORD[(192-128)+r9],ymm7
133	vpxor	ymm9,ymm9,ymm9
134	vmovdqa	YMMWORD[(224-128)+r9],ymm8
135
136	vpmuludq	ymm0,ymm10,YMMWORD[((0-128))+rsi]
137	vpbroadcastq	ymm11,QWORD[((32-128))+rsi]
138	vmovdqu	YMMWORD[(288-192)+rbx],ymm9
139	vpmuludq	ymm1,ymm1,ymm10
140	vmovdqu	YMMWORD[(320-448)+r12],ymm9
141	vpmuludq	ymm2,ymm2,ymm10
142	vmovdqu	YMMWORD[(352-448)+r12],ymm9
143	vpmuludq	ymm3,ymm3,ymm10
144	vmovdqu	YMMWORD[(384-448)+r12],ymm9
145	vpmuludq	ymm4,ymm4,ymm10
146	vmovdqu	YMMWORD[(416-448)+r12],ymm9
147	vpmuludq	ymm5,ymm5,ymm10
148	vmovdqu	YMMWORD[(448-448)+r12],ymm9
149	vpmuludq	ymm6,ymm6,ymm10
150	vmovdqu	YMMWORD[(480-448)+r12],ymm9
151	vpmuludq	ymm7,ymm7,ymm10
152	vmovdqu	YMMWORD[(512-448)+r12],ymm9
153	vpmuludq	ymm8,ymm8,ymm10
154	vpbroadcastq	ymm10,QWORD[((64-128))+rsi]
155	vmovdqu	YMMWORD[(544-448)+r12],ymm9
156
157	mov	r15,rsi
158	mov	r14d,4
159	jmp	NEAR $L$sqr_entry_1024
160ALIGN	32
161$L$OOP_SQR_1024:
162	vpbroadcastq	ymm11,QWORD[((32-128))+r15]
163	vpmuludq	ymm0,ymm10,YMMWORD[((0-128))+rsi]
164	vpaddq	ymm0,ymm0,YMMWORD[((0-192))+rbx]
165	vpmuludq	ymm1,ymm10,YMMWORD[((0-128))+r9]
166	vpaddq	ymm1,ymm1,YMMWORD[((32-192))+rbx]
167	vpmuludq	ymm2,ymm10,YMMWORD[((32-128))+r9]
168	vpaddq	ymm2,ymm2,YMMWORD[((64-192))+rbx]
169	vpmuludq	ymm3,ymm10,YMMWORD[((64-128))+r9]
170	vpaddq	ymm3,ymm3,YMMWORD[((96-192))+rbx]
171	vpmuludq	ymm4,ymm10,YMMWORD[((96-128))+r9]
172	vpaddq	ymm4,ymm4,YMMWORD[((128-192))+rbx]
173	vpmuludq	ymm5,ymm10,YMMWORD[((128-128))+r9]
174	vpaddq	ymm5,ymm5,YMMWORD[((160-192))+rbx]
175	vpmuludq	ymm6,ymm10,YMMWORD[((160-128))+r9]
176	vpaddq	ymm6,ymm6,YMMWORD[((192-192))+rbx]
177	vpmuludq	ymm7,ymm10,YMMWORD[((192-128))+r9]
178	vpaddq	ymm7,ymm7,YMMWORD[((224-192))+rbx]
179	vpmuludq	ymm8,ymm10,YMMWORD[((224-128))+r9]
180	vpbroadcastq	ymm10,QWORD[((64-128))+r15]
181	vpaddq	ymm8,ymm8,YMMWORD[((256-192))+rbx]
182$L$sqr_entry_1024:
183	vmovdqu	YMMWORD[(0-192)+rbx],ymm0
184	vmovdqu	YMMWORD[(32-192)+rbx],ymm1
185
186	vpmuludq	ymm12,ymm11,YMMWORD[((32-128))+rsi]
187	vpaddq	ymm2,ymm2,ymm12
188	vpmuludq	ymm14,ymm11,YMMWORD[((32-128))+r9]
189	vpaddq	ymm3,ymm3,ymm14
190	vpmuludq	ymm13,ymm11,YMMWORD[((64-128))+r9]
191	vpaddq	ymm4,ymm4,ymm13
192	vpmuludq	ymm12,ymm11,YMMWORD[((96-128))+r9]
193	vpaddq	ymm5,ymm5,ymm12
194	vpmuludq	ymm14,ymm11,YMMWORD[((128-128))+r9]
195	vpaddq	ymm6,ymm6,ymm14
196	vpmuludq	ymm13,ymm11,YMMWORD[((160-128))+r9]
197	vpaddq	ymm7,ymm7,ymm13
198	vpmuludq	ymm12,ymm11,YMMWORD[((192-128))+r9]
199	vpaddq	ymm8,ymm8,ymm12
200	vpmuludq	ymm0,ymm11,YMMWORD[((224-128))+r9]
201	vpbroadcastq	ymm11,QWORD[((96-128))+r15]
202	vpaddq	ymm0,ymm0,YMMWORD[((288-192))+rbx]
203
204	vmovdqu	YMMWORD[(64-192)+rbx],ymm2
205	vmovdqu	YMMWORD[(96-192)+rbx],ymm3
206
207	vpmuludq	ymm13,ymm10,YMMWORD[((64-128))+rsi]
208	vpaddq	ymm4,ymm4,ymm13
209	vpmuludq	ymm12,ymm10,YMMWORD[((64-128))+r9]
210	vpaddq	ymm5,ymm5,ymm12
211	vpmuludq	ymm14,ymm10,YMMWORD[((96-128))+r9]
212	vpaddq	ymm6,ymm6,ymm14
213	vpmuludq	ymm13,ymm10,YMMWORD[((128-128))+r9]
214	vpaddq	ymm7,ymm7,ymm13
215	vpmuludq	ymm12,ymm10,YMMWORD[((160-128))+r9]
216	vpaddq	ymm8,ymm8,ymm12
217	vpmuludq	ymm14,ymm10,YMMWORD[((192-128))+r9]
218	vpaddq	ymm0,ymm0,ymm14
219	vpmuludq	ymm1,ymm10,YMMWORD[((224-128))+r9]
220	vpbroadcastq	ymm10,QWORD[((128-128))+r15]
221	vpaddq	ymm1,ymm1,YMMWORD[((320-448))+r12]
222
223	vmovdqu	YMMWORD[(128-192)+rbx],ymm4
224	vmovdqu	YMMWORD[(160-192)+rbx],ymm5
225
226	vpmuludq	ymm12,ymm11,YMMWORD[((96-128))+rsi]
227	vpaddq	ymm6,ymm6,ymm12
228	vpmuludq	ymm14,ymm11,YMMWORD[((96-128))+r9]
229	vpaddq	ymm7,ymm7,ymm14
230	vpmuludq	ymm13,ymm11,YMMWORD[((128-128))+r9]
231	vpaddq	ymm8,ymm8,ymm13
232	vpmuludq	ymm12,ymm11,YMMWORD[((160-128))+r9]
233	vpaddq	ymm0,ymm0,ymm12
234	vpmuludq	ymm14,ymm11,YMMWORD[((192-128))+r9]
235	vpaddq	ymm1,ymm1,ymm14
236	vpmuludq	ymm2,ymm11,YMMWORD[((224-128))+r9]
237	vpbroadcastq	ymm11,QWORD[((160-128))+r15]
238	vpaddq	ymm2,ymm2,YMMWORD[((352-448))+r12]
239
240	vmovdqu	YMMWORD[(192-192)+rbx],ymm6
241	vmovdqu	YMMWORD[(224-192)+rbx],ymm7
242
243	vpmuludq	ymm12,ymm10,YMMWORD[((128-128))+rsi]
244	vpaddq	ymm8,ymm8,ymm12
245	vpmuludq	ymm14,ymm10,YMMWORD[((128-128))+r9]
246	vpaddq	ymm0,ymm0,ymm14
247	vpmuludq	ymm13,ymm10,YMMWORD[((160-128))+r9]
248	vpaddq	ymm1,ymm1,ymm13
249	vpmuludq	ymm12,ymm10,YMMWORD[((192-128))+r9]
250	vpaddq	ymm2,ymm2,ymm12
251	vpmuludq	ymm3,ymm10,YMMWORD[((224-128))+r9]
252	vpbroadcastq	ymm10,QWORD[((192-128))+r15]
253	vpaddq	ymm3,ymm3,YMMWORD[((384-448))+r12]
254
255	vmovdqu	YMMWORD[(256-192)+rbx],ymm8
256	vmovdqu	YMMWORD[(288-192)+rbx],ymm0
257	lea	rbx,[8+rbx]
258
259	vpmuludq	ymm13,ymm11,YMMWORD[((160-128))+rsi]
260	vpaddq	ymm1,ymm1,ymm13
261	vpmuludq	ymm12,ymm11,YMMWORD[((160-128))+r9]
262	vpaddq	ymm2,ymm2,ymm12
263	vpmuludq	ymm14,ymm11,YMMWORD[((192-128))+r9]
264	vpaddq	ymm3,ymm3,ymm14
265	vpmuludq	ymm4,ymm11,YMMWORD[((224-128))+r9]
266	vpbroadcastq	ymm11,QWORD[((224-128))+r15]
267	vpaddq	ymm4,ymm4,YMMWORD[((416-448))+r12]
268
269	vmovdqu	YMMWORD[(320-448)+r12],ymm1
270	vmovdqu	YMMWORD[(352-448)+r12],ymm2
271
272	vpmuludq	ymm12,ymm10,YMMWORD[((192-128))+rsi]
273	vpaddq	ymm3,ymm3,ymm12
274	vpmuludq	ymm14,ymm10,YMMWORD[((192-128))+r9]
275	vpbroadcastq	ymm0,QWORD[((256-128))+r15]
276	vpaddq	ymm4,ymm4,ymm14
277	vpmuludq	ymm5,ymm10,YMMWORD[((224-128))+r9]
278	vpbroadcastq	ymm10,QWORD[((0+8-128))+r15]
279	vpaddq	ymm5,ymm5,YMMWORD[((448-448))+r12]
280
281	vmovdqu	YMMWORD[(384-448)+r12],ymm3
282	vmovdqu	YMMWORD[(416-448)+r12],ymm4
283	lea	r15,[8+r15]
284
285	vpmuludq	ymm12,ymm11,YMMWORD[((224-128))+rsi]
286	vpaddq	ymm5,ymm5,ymm12
287	vpmuludq	ymm6,ymm11,YMMWORD[((224-128))+r9]
288	vpaddq	ymm6,ymm6,YMMWORD[((480-448))+r12]
289
290	vpmuludq	ymm7,ymm0,YMMWORD[((256-128))+rsi]
291	vmovdqu	YMMWORD[(448-448)+r12],ymm5
292	vpaddq	ymm7,ymm7,YMMWORD[((512-448))+r12]
293	vmovdqu	YMMWORD[(480-448)+r12],ymm6
294	vmovdqu	YMMWORD[(512-448)+r12],ymm7
295	lea	r12,[8+r12]
296
297	dec	r14d
298	jnz	NEAR $L$OOP_SQR_1024
299
300	vmovdqu	ymm8,YMMWORD[256+rsp]
301	vmovdqu	ymm1,YMMWORD[288+rsp]
302	vmovdqu	ymm2,YMMWORD[320+rsp]
303	lea	rbx,[192+rsp]
304
305	vpsrlq	ymm14,ymm8,29
306	vpand	ymm8,ymm8,ymm15
307	vpsrlq	ymm11,ymm1,29
308	vpand	ymm1,ymm1,ymm15
309
310	vpermq	ymm14,ymm14,0x93
311	vpxor	ymm9,ymm9,ymm9
312	vpermq	ymm11,ymm11,0x93
313
314	vpblendd	ymm10,ymm14,ymm9,3
315	vpblendd	ymm14,ymm11,ymm14,3
316	vpaddq	ymm8,ymm8,ymm10
317	vpblendd	ymm11,ymm9,ymm11,3
318	vpaddq	ymm1,ymm1,ymm14
319	vpaddq	ymm2,ymm2,ymm11
320	vmovdqu	YMMWORD[(288-192)+rbx],ymm1
321	vmovdqu	YMMWORD[(320-192)+rbx],ymm2
322
323	mov	rax,QWORD[rsp]
324	mov	r10,QWORD[8+rsp]
325	mov	r11,QWORD[16+rsp]
326	mov	r12,QWORD[24+rsp]
327	vmovdqu	ymm1,YMMWORD[32+rsp]
328	vmovdqu	ymm2,YMMWORD[((64-192))+rbx]
329	vmovdqu	ymm3,YMMWORD[((96-192))+rbx]
330	vmovdqu	ymm4,YMMWORD[((128-192))+rbx]
331	vmovdqu	ymm5,YMMWORD[((160-192))+rbx]
332	vmovdqu	ymm6,YMMWORD[((192-192))+rbx]
333	vmovdqu	ymm7,YMMWORD[((224-192))+rbx]
334
335	mov	r9,rax
336	imul	eax,ecx
337	and	eax,0x1fffffff
338	vmovd	xmm12,eax
339
340	mov	rdx,rax
341	imul	rax,QWORD[((-128))+r13]
342	vpbroadcastq	ymm12,xmm12
343	add	r9,rax
344	mov	rax,rdx
345	imul	rax,QWORD[((8-128))+r13]
346	shr	r9,29
347	add	r10,rax
348	mov	rax,rdx
349	imul	rax,QWORD[((16-128))+r13]
350	add	r10,r9
351	add	r11,rax
352	imul	rdx,QWORD[((24-128))+r13]
353	add	r12,rdx
354
355	mov	rax,r10
356	imul	eax,ecx
357	and	eax,0x1fffffff
358
359	mov	r14d,9
360	jmp	NEAR $L$OOP_REDUCE_1024
361
362ALIGN	32
363$L$OOP_REDUCE_1024:
364	vmovd	xmm13,eax
365	vpbroadcastq	ymm13,xmm13
366
367	vpmuludq	ymm10,ymm12,YMMWORD[((32-128))+r13]
368	mov	rdx,rax
369	imul	rax,QWORD[((-128))+r13]
370	vpaddq	ymm1,ymm1,ymm10
371	add	r10,rax
372	vpmuludq	ymm14,ymm12,YMMWORD[((64-128))+r13]
373	mov	rax,rdx
374	imul	rax,QWORD[((8-128))+r13]
375	vpaddq	ymm2,ymm2,ymm14
376	vpmuludq	ymm11,ymm12,YMMWORD[((96-128))+r13]
377DB	0x67
378	add	r11,rax
379DB	0x67
380	mov	rax,rdx
381	imul	rax,QWORD[((16-128))+r13]
382	shr	r10,29
383	vpaddq	ymm3,ymm3,ymm11
384	vpmuludq	ymm10,ymm12,YMMWORD[((128-128))+r13]
385	add	r12,rax
386	add	r11,r10
387	vpaddq	ymm4,ymm4,ymm10
388	vpmuludq	ymm14,ymm12,YMMWORD[((160-128))+r13]
389	mov	rax,r11
390	imul	eax,ecx
391	vpaddq	ymm5,ymm5,ymm14
392	vpmuludq	ymm11,ymm12,YMMWORD[((192-128))+r13]
393	and	eax,0x1fffffff
394	vpaddq	ymm6,ymm6,ymm11
395	vpmuludq	ymm10,ymm12,YMMWORD[((224-128))+r13]
396	vpaddq	ymm7,ymm7,ymm10
397	vpmuludq	ymm14,ymm12,YMMWORD[((256-128))+r13]
398	vmovd	xmm12,eax
399
400	vpaddq	ymm8,ymm8,ymm14
401
402	vpbroadcastq	ymm12,xmm12
403
404	vpmuludq	ymm11,ymm13,YMMWORD[((32-8-128))+r13]
405	vmovdqu	ymm14,YMMWORD[((96-8-128))+r13]
406	mov	rdx,rax
407	imul	rax,QWORD[((-128))+r13]
408	vpaddq	ymm1,ymm1,ymm11
409	vpmuludq	ymm10,ymm13,YMMWORD[((64-8-128))+r13]
410	vmovdqu	ymm11,YMMWORD[((128-8-128))+r13]
411	add	r11,rax
412	mov	rax,rdx
413	imul	rax,QWORD[((8-128))+r13]
414	vpaddq	ymm2,ymm2,ymm10
415	add	rax,r12
416	shr	r11,29
417	vpmuludq	ymm14,ymm14,ymm13
418	vmovdqu	ymm10,YMMWORD[((160-8-128))+r13]
419	add	rax,r11
420	vpaddq	ymm3,ymm3,ymm14
421	vpmuludq	ymm11,ymm11,ymm13
422	vmovdqu	ymm14,YMMWORD[((192-8-128))+r13]
423DB	0x67
424	mov	r12,rax
425	imul	eax,ecx
426	vpaddq	ymm4,ymm4,ymm11
427	vpmuludq	ymm10,ymm10,ymm13
428DB	0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00
429	and	eax,0x1fffffff
430	vpaddq	ymm5,ymm5,ymm10
431	vpmuludq	ymm14,ymm14,ymm13
432	vmovdqu	ymm10,YMMWORD[((256-8-128))+r13]
433	vpaddq	ymm6,ymm6,ymm14
434	vpmuludq	ymm11,ymm11,ymm13
435	vmovdqu	ymm9,YMMWORD[((288-8-128))+r13]
436	vmovd	xmm0,eax
437	imul	rax,QWORD[((-128))+r13]
438	vpaddq	ymm7,ymm7,ymm11
439	vpmuludq	ymm10,ymm10,ymm13
440	vmovdqu	ymm14,YMMWORD[((32-16-128))+r13]
441	vpbroadcastq	ymm0,xmm0
442	vpaddq	ymm8,ymm8,ymm10
443	vpmuludq	ymm9,ymm9,ymm13
444	vmovdqu	ymm11,YMMWORD[((64-16-128))+r13]
445	add	r12,rax
446
447	vmovdqu	ymm13,YMMWORD[((32-24-128))+r13]
448	vpmuludq	ymm14,ymm14,ymm12
449	vmovdqu	ymm10,YMMWORD[((96-16-128))+r13]
450	vpaddq	ymm1,ymm1,ymm14
451	vpmuludq	ymm13,ymm13,ymm0
452	vpmuludq	ymm11,ymm11,ymm12
453DB	0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff
454	vpaddq	ymm13,ymm13,ymm1
455	vpaddq	ymm2,ymm2,ymm11
456	vpmuludq	ymm10,ymm10,ymm12
457	vmovdqu	ymm11,YMMWORD[((160-16-128))+r13]
458DB	0x67
459	vmovq	rax,xmm13
460	vmovdqu	YMMWORD[rsp],ymm13
461	vpaddq	ymm3,ymm3,ymm10
462	vpmuludq	ymm14,ymm14,ymm12
463	vmovdqu	ymm10,YMMWORD[((192-16-128))+r13]
464	vpaddq	ymm4,ymm4,ymm14
465	vpmuludq	ymm11,ymm11,ymm12
466	vmovdqu	ymm14,YMMWORD[((224-16-128))+r13]
467	vpaddq	ymm5,ymm5,ymm11
468	vpmuludq	ymm10,ymm10,ymm12
469	vmovdqu	ymm11,YMMWORD[((256-16-128))+r13]
470	vpaddq	ymm6,ymm6,ymm10
471	vpmuludq	ymm14,ymm14,ymm12
472	shr	r12,29
473	vmovdqu	ymm10,YMMWORD[((288-16-128))+r13]
474	add	rax,r12
475	vpaddq	ymm7,ymm7,ymm14
476	vpmuludq	ymm11,ymm11,ymm12
477
478	mov	r9,rax
479	imul	eax,ecx
480	vpaddq	ymm8,ymm8,ymm11
481	vpmuludq	ymm10,ymm10,ymm12
482	and	eax,0x1fffffff
483	vmovd	xmm12,eax
484	vmovdqu	ymm11,YMMWORD[((96-24-128))+r13]
485DB	0x67
486	vpaddq	ymm9,ymm9,ymm10
487	vpbroadcastq	ymm12,xmm12
488
489	vpmuludq	ymm14,ymm0,YMMWORD[((64-24-128))+r13]
490	vmovdqu	ymm10,YMMWORD[((128-24-128))+r13]
491	mov	rdx,rax
492	imul	rax,QWORD[((-128))+r13]
493	mov	r10,QWORD[8+rsp]
494	vpaddq	ymm1,ymm2,ymm14
495	vpmuludq	ymm11,ymm11,ymm0
496	vmovdqu	ymm14,YMMWORD[((160-24-128))+r13]
497	add	r9,rax
498	mov	rax,rdx
499	imul	rax,QWORD[((8-128))+r13]
500DB	0x67
501	shr	r9,29
502	mov	r11,QWORD[16+rsp]
503	vpaddq	ymm2,ymm3,ymm11
504	vpmuludq	ymm10,ymm10,ymm0
505	vmovdqu	ymm11,YMMWORD[((192-24-128))+r13]
506	add	r10,rax
507	mov	rax,rdx
508	imul	rax,QWORD[((16-128))+r13]
509	vpaddq	ymm3,ymm4,ymm10
510	vpmuludq	ymm14,ymm14,ymm0
511	vmovdqu	ymm10,YMMWORD[((224-24-128))+r13]
512	imul	rdx,QWORD[((24-128))+r13]
513	add	r11,rax
514	lea	rax,[r10*1+r9]
515	vpaddq	ymm4,ymm5,ymm14
516	vpmuludq	ymm11,ymm11,ymm0
517	vmovdqu	ymm14,YMMWORD[((256-24-128))+r13]
518	mov	r10,rax
519	imul	eax,ecx
520	vpmuludq	ymm10,ymm10,ymm0
521	vpaddq	ymm5,ymm6,ymm11
522	vmovdqu	ymm11,YMMWORD[((288-24-128))+r13]
523	and	eax,0x1fffffff
524	vpaddq	ymm6,ymm7,ymm10
525	vpmuludq	ymm14,ymm14,ymm0
526	add	rdx,QWORD[24+rsp]
527	vpaddq	ymm7,ymm8,ymm14
528	vpmuludq	ymm11,ymm11,ymm0
529	vpaddq	ymm8,ymm9,ymm11
530	vmovq	xmm9,r12
531	mov	r12,rdx
532
533	dec	r14d
534	jnz	NEAR $L$OOP_REDUCE_1024
535	lea	r12,[448+rsp]
536	vpaddq	ymm0,ymm13,ymm9
537	vpxor	ymm9,ymm9,ymm9
538
539	vpaddq	ymm0,ymm0,YMMWORD[((288-192))+rbx]
540	vpaddq	ymm1,ymm1,YMMWORD[((320-448))+r12]
541	vpaddq	ymm2,ymm2,YMMWORD[((352-448))+r12]
542	vpaddq	ymm3,ymm3,YMMWORD[((384-448))+r12]
543	vpaddq	ymm4,ymm4,YMMWORD[((416-448))+r12]
544	vpaddq	ymm5,ymm5,YMMWORD[((448-448))+r12]
545	vpaddq	ymm6,ymm6,YMMWORD[((480-448))+r12]
546	vpaddq	ymm7,ymm7,YMMWORD[((512-448))+r12]
547	vpaddq	ymm8,ymm8,YMMWORD[((544-448))+r12]
548
549	vpsrlq	ymm14,ymm0,29
550	vpand	ymm0,ymm0,ymm15
551	vpsrlq	ymm11,ymm1,29
552	vpand	ymm1,ymm1,ymm15
553	vpsrlq	ymm12,ymm2,29
554	vpermq	ymm14,ymm14,0x93
555	vpand	ymm2,ymm2,ymm15
556	vpsrlq	ymm13,ymm3,29
557	vpermq	ymm11,ymm11,0x93
558	vpand	ymm3,ymm3,ymm15
559	vpermq	ymm12,ymm12,0x93
560
561	vpblendd	ymm10,ymm14,ymm9,3
562	vpermq	ymm13,ymm13,0x93
563	vpblendd	ymm14,ymm11,ymm14,3
564	vpaddq	ymm0,ymm0,ymm10
565	vpblendd	ymm11,ymm12,ymm11,3
566	vpaddq	ymm1,ymm1,ymm14
567	vpblendd	ymm12,ymm13,ymm12,3
568	vpaddq	ymm2,ymm2,ymm11
569	vpblendd	ymm13,ymm9,ymm13,3
570	vpaddq	ymm3,ymm3,ymm12
571	vpaddq	ymm4,ymm4,ymm13
572
573	vpsrlq	ymm14,ymm0,29
574	vpand	ymm0,ymm0,ymm15
575	vpsrlq	ymm11,ymm1,29
576	vpand	ymm1,ymm1,ymm15
577	vpsrlq	ymm12,ymm2,29
578	vpermq	ymm14,ymm14,0x93
579	vpand	ymm2,ymm2,ymm15
580	vpsrlq	ymm13,ymm3,29
581	vpermq	ymm11,ymm11,0x93
582	vpand	ymm3,ymm3,ymm15
583	vpermq	ymm12,ymm12,0x93
584
585	vpblendd	ymm10,ymm14,ymm9,3
586	vpermq	ymm13,ymm13,0x93
587	vpblendd	ymm14,ymm11,ymm14,3
588	vpaddq	ymm0,ymm0,ymm10
589	vpblendd	ymm11,ymm12,ymm11,3
590	vpaddq	ymm1,ymm1,ymm14
591	vmovdqu	YMMWORD[(0-128)+rdi],ymm0
592	vpblendd	ymm12,ymm13,ymm12,3
593	vpaddq	ymm2,ymm2,ymm11
594	vmovdqu	YMMWORD[(32-128)+rdi],ymm1
595	vpblendd	ymm13,ymm9,ymm13,3
596	vpaddq	ymm3,ymm3,ymm12
597	vmovdqu	YMMWORD[(64-128)+rdi],ymm2
598	vpaddq	ymm4,ymm4,ymm13
599	vmovdqu	YMMWORD[(96-128)+rdi],ymm3
600	vpsrlq	ymm14,ymm4,29
601	vpand	ymm4,ymm4,ymm15
602	vpsrlq	ymm11,ymm5,29
603	vpand	ymm5,ymm5,ymm15
604	vpsrlq	ymm12,ymm6,29
605	vpermq	ymm14,ymm14,0x93
606	vpand	ymm6,ymm6,ymm15
607	vpsrlq	ymm13,ymm7,29
608	vpermq	ymm11,ymm11,0x93
609	vpand	ymm7,ymm7,ymm15
610	vpsrlq	ymm0,ymm8,29
611	vpermq	ymm12,ymm12,0x93
612	vpand	ymm8,ymm8,ymm15
613	vpermq	ymm13,ymm13,0x93
614
615	vpblendd	ymm10,ymm14,ymm9,3
616	vpermq	ymm0,ymm0,0x93
617	vpblendd	ymm14,ymm11,ymm14,3
618	vpaddq	ymm4,ymm4,ymm10
619	vpblendd	ymm11,ymm12,ymm11,3
620	vpaddq	ymm5,ymm5,ymm14
621	vpblendd	ymm12,ymm13,ymm12,3
622	vpaddq	ymm6,ymm6,ymm11
623	vpblendd	ymm13,ymm0,ymm13,3
624	vpaddq	ymm7,ymm7,ymm12
625	vpaddq	ymm8,ymm8,ymm13
626
627	vpsrlq	ymm14,ymm4,29
628	vpand	ymm4,ymm4,ymm15
629	vpsrlq	ymm11,ymm5,29
630	vpand	ymm5,ymm5,ymm15
631	vpsrlq	ymm12,ymm6,29
632	vpermq	ymm14,ymm14,0x93
633	vpand	ymm6,ymm6,ymm15
634	vpsrlq	ymm13,ymm7,29
635	vpermq	ymm11,ymm11,0x93
636	vpand	ymm7,ymm7,ymm15
637	vpsrlq	ymm0,ymm8,29
638	vpermq	ymm12,ymm12,0x93
639	vpand	ymm8,ymm8,ymm15
640	vpermq	ymm13,ymm13,0x93
641
642	vpblendd	ymm10,ymm14,ymm9,3
643	vpermq	ymm0,ymm0,0x93
644	vpblendd	ymm14,ymm11,ymm14,3
645	vpaddq	ymm4,ymm4,ymm10
646	vpblendd	ymm11,ymm12,ymm11,3
647	vpaddq	ymm5,ymm5,ymm14
648	vmovdqu	YMMWORD[(128-128)+rdi],ymm4
649	vpblendd	ymm12,ymm13,ymm12,3
650	vpaddq	ymm6,ymm6,ymm11
651	vmovdqu	YMMWORD[(160-128)+rdi],ymm5
652	vpblendd	ymm13,ymm0,ymm13,3
653	vpaddq	ymm7,ymm7,ymm12
654	vmovdqu	YMMWORD[(192-128)+rdi],ymm6
655	vpaddq	ymm8,ymm8,ymm13
656	vmovdqu	YMMWORD[(224-128)+rdi],ymm7
657	vmovdqu	YMMWORD[(256-128)+rdi],ymm8
658
659	mov	rsi,rdi
660	dec	r8d
661	jne	NEAR $L$OOP_GRANDE_SQR_1024
662
663	vzeroall
664	mov	rax,rbp
665
666$L$sqr_1024_in_tail:
667	movaps	xmm6,XMMWORD[((-216))+rax]
668	movaps	xmm7,XMMWORD[((-200))+rax]
669	movaps	xmm8,XMMWORD[((-184))+rax]
670	movaps	xmm9,XMMWORD[((-168))+rax]
671	movaps	xmm10,XMMWORD[((-152))+rax]
672	movaps	xmm11,XMMWORD[((-136))+rax]
673	movaps	xmm12,XMMWORD[((-120))+rax]
674	movaps	xmm13,XMMWORD[((-104))+rax]
675	movaps	xmm14,XMMWORD[((-88))+rax]
676	movaps	xmm15,XMMWORD[((-72))+rax]
677	mov	r15,QWORD[((-48))+rax]
678
679	mov	r14,QWORD[((-40))+rax]
680
681	mov	r13,QWORD[((-32))+rax]
682
683	mov	r12,QWORD[((-24))+rax]
684
685	mov	rbp,QWORD[((-16))+rax]
686
687	mov	rbx,QWORD[((-8))+rax]
688
689	lea	rsp,[rax]
690
691$L$sqr_1024_epilogue:
692	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
693	mov	rsi,QWORD[16+rsp]
694	DB	0F3h,0C3h		;repret
695
696$L$SEH_end_rsaz_1024_sqr_avx2:
697global	rsaz_1024_mul_avx2
698
699ALIGN	64
700rsaz_1024_mul_avx2:
701	mov	QWORD[8+rsp],rdi	;WIN64 prologue
702	mov	QWORD[16+rsp],rsi
703	mov	rax,rsp
704$L$SEH_begin_rsaz_1024_mul_avx2:
705	mov	rdi,rcx
706	mov	rsi,rdx
707	mov	rdx,r8
708	mov	rcx,r9
709	mov	r8,QWORD[40+rsp]
710
711
712
713	lea	rax,[rsp]
714
715	push	rbx
716
717	push	rbp
718
719	push	r12
720
721	push	r13
722
723	push	r14
724
725	push	r15
726
727	vzeroupper
728	lea	rsp,[((-168))+rsp]
729	vmovaps	XMMWORD[(-216)+rax],xmm6
730	vmovaps	XMMWORD[(-200)+rax],xmm7
731	vmovaps	XMMWORD[(-184)+rax],xmm8
732	vmovaps	XMMWORD[(-168)+rax],xmm9
733	vmovaps	XMMWORD[(-152)+rax],xmm10
734	vmovaps	XMMWORD[(-136)+rax],xmm11
735	vmovaps	XMMWORD[(-120)+rax],xmm12
736	vmovaps	XMMWORD[(-104)+rax],xmm13
737	vmovaps	XMMWORD[(-88)+rax],xmm14
738	vmovaps	XMMWORD[(-72)+rax],xmm15
739$L$mul_1024_body:
740	mov	rbp,rax
741
742	vzeroall
743	mov	r13,rdx
744	sub	rsp,64
745
746
747
748
749
750
751DB	0x67,0x67
752	mov	r15,rsi
753	and	r15,4095
754	add	r15,32*10
755	shr	r15,12
756	mov	r15,rsi
757	cmovnz	rsi,r13
758	cmovnz	r13,r15
759
760	mov	r15,rcx
761	sub	rsi,-128
762	sub	rcx,-128
763	sub	rdi,-128
764
765	and	r15,4095
766	add	r15,32*10
767DB	0x67,0x67
768	shr	r15,12
769	jz	NEAR $L$mul_1024_no_n_copy
770
771
772
773
774
775	sub	rsp,32*10
776	vmovdqu	ymm0,YMMWORD[((0-128))+rcx]
777	and	rsp,-512
778	vmovdqu	ymm1,YMMWORD[((32-128))+rcx]
779	vmovdqu	ymm2,YMMWORD[((64-128))+rcx]
780	vmovdqu	ymm3,YMMWORD[((96-128))+rcx]
781	vmovdqu	ymm4,YMMWORD[((128-128))+rcx]
782	vmovdqu	ymm5,YMMWORD[((160-128))+rcx]
783	vmovdqu	ymm6,YMMWORD[((192-128))+rcx]
784	vmovdqu	ymm7,YMMWORD[((224-128))+rcx]
785	vmovdqu	ymm8,YMMWORD[((256-128))+rcx]
786	lea	rcx,[((64+128))+rsp]
787	vmovdqu	YMMWORD[(0-128)+rcx],ymm0
788	vpxor	ymm0,ymm0,ymm0
789	vmovdqu	YMMWORD[(32-128)+rcx],ymm1
790	vpxor	ymm1,ymm1,ymm1
791	vmovdqu	YMMWORD[(64-128)+rcx],ymm2
792	vpxor	ymm2,ymm2,ymm2
793	vmovdqu	YMMWORD[(96-128)+rcx],ymm3
794	vpxor	ymm3,ymm3,ymm3
795	vmovdqu	YMMWORD[(128-128)+rcx],ymm4
796	vpxor	ymm4,ymm4,ymm4
797	vmovdqu	YMMWORD[(160-128)+rcx],ymm5
798	vpxor	ymm5,ymm5,ymm5
799	vmovdqu	YMMWORD[(192-128)+rcx],ymm6
800	vpxor	ymm6,ymm6,ymm6
801	vmovdqu	YMMWORD[(224-128)+rcx],ymm7
802	vpxor	ymm7,ymm7,ymm7
803	vmovdqu	YMMWORD[(256-128)+rcx],ymm8
804	vmovdqa	ymm8,ymm0
805	vmovdqu	YMMWORD[(288-128)+rcx],ymm9
806$L$mul_1024_no_n_copy:
807	and	rsp,-64
808
809	mov	rbx,QWORD[r13]
810	vpbroadcastq	ymm10,QWORD[r13]
811	vmovdqu	YMMWORD[rsp],ymm0
812	xor	r9,r9
813DB	0x67
814	xor	r10,r10
815	xor	r11,r11
816	xor	r12,r12
817
818	vmovdqu	ymm15,YMMWORD[$L$and_mask]
819	mov	r14d,9
820	vmovdqu	YMMWORD[(288-128)+rdi],ymm9
821	jmp	NEAR $L$oop_mul_1024
822
823ALIGN	32
824$L$oop_mul_1024:
825	vpsrlq	ymm9,ymm3,29
826	mov	rax,rbx
827	imul	rax,QWORD[((-128))+rsi]
828	add	rax,r9
829	mov	r10,rbx
830	imul	r10,QWORD[((8-128))+rsi]
831	add	r10,QWORD[8+rsp]
832
833	mov	r9,rax
834	imul	eax,r8d
835	and	eax,0x1fffffff
836
837	mov	r11,rbx
838	imul	r11,QWORD[((16-128))+rsi]
839	add	r11,QWORD[16+rsp]
840
841	mov	r12,rbx
842	imul	r12,QWORD[((24-128))+rsi]
843	add	r12,QWORD[24+rsp]
844	vpmuludq	ymm0,ymm10,YMMWORD[((32-128))+rsi]
845	vmovd	xmm11,eax
846	vpaddq	ymm1,ymm1,ymm0
847	vpmuludq	ymm12,ymm10,YMMWORD[((64-128))+rsi]
848	vpbroadcastq	ymm11,xmm11
849	vpaddq	ymm2,ymm2,ymm12
850	vpmuludq	ymm13,ymm10,YMMWORD[((96-128))+rsi]
851	vpand	ymm3,ymm3,ymm15
852	vpaddq	ymm3,ymm3,ymm13
853	vpmuludq	ymm0,ymm10,YMMWORD[((128-128))+rsi]
854	vpaddq	ymm4,ymm4,ymm0
855	vpmuludq	ymm12,ymm10,YMMWORD[((160-128))+rsi]
856	vpaddq	ymm5,ymm5,ymm12
857	vpmuludq	ymm13,ymm10,YMMWORD[((192-128))+rsi]
858	vpaddq	ymm6,ymm6,ymm13
859	vpmuludq	ymm0,ymm10,YMMWORD[((224-128))+rsi]
860	vpermq	ymm9,ymm9,0x93
861	vpaddq	ymm7,ymm7,ymm0
862	vpmuludq	ymm12,ymm10,YMMWORD[((256-128))+rsi]
863	vpbroadcastq	ymm10,QWORD[8+r13]
864	vpaddq	ymm8,ymm8,ymm12
865
866	mov	rdx,rax
867	imul	rax,QWORD[((-128))+rcx]
868	add	r9,rax
869	mov	rax,rdx
870	imul	rax,QWORD[((8-128))+rcx]
871	add	r10,rax
872	mov	rax,rdx
873	imul	rax,QWORD[((16-128))+rcx]
874	add	r11,rax
875	shr	r9,29
876	imul	rdx,QWORD[((24-128))+rcx]
877	add	r12,rdx
878	add	r10,r9
879
880	vpmuludq	ymm13,ymm11,YMMWORD[((32-128))+rcx]
881	vmovq	rbx,xmm10
882	vpaddq	ymm1,ymm1,ymm13
883	vpmuludq	ymm0,ymm11,YMMWORD[((64-128))+rcx]
884	vpaddq	ymm2,ymm2,ymm0
885	vpmuludq	ymm12,ymm11,YMMWORD[((96-128))+rcx]
886	vpaddq	ymm3,ymm3,ymm12
887	vpmuludq	ymm13,ymm11,YMMWORD[((128-128))+rcx]
888	vpaddq	ymm4,ymm4,ymm13
889	vpmuludq	ymm0,ymm11,YMMWORD[((160-128))+rcx]
890	vpaddq	ymm5,ymm5,ymm0
891	vpmuludq	ymm12,ymm11,YMMWORD[((192-128))+rcx]
892	vpaddq	ymm6,ymm6,ymm12
893	vpmuludq	ymm13,ymm11,YMMWORD[((224-128))+rcx]
894	vpblendd	ymm12,ymm9,ymm14,3
895	vpaddq	ymm7,ymm7,ymm13
896	vpmuludq	ymm0,ymm11,YMMWORD[((256-128))+rcx]
897	vpaddq	ymm3,ymm3,ymm12
898	vpaddq	ymm8,ymm8,ymm0
899
900	mov	rax,rbx
901	imul	rax,QWORD[((-128))+rsi]
902	add	r10,rax
903	vmovdqu	ymm12,YMMWORD[((-8+32-128))+rsi]
904	mov	rax,rbx
905	imul	rax,QWORD[((8-128))+rsi]
906	add	r11,rax
907	vmovdqu	ymm13,YMMWORD[((-8+64-128))+rsi]
908
909	mov	rax,r10
910	vpblendd	ymm9,ymm9,ymm14,0xfc
911	imul	eax,r8d
912	vpaddq	ymm4,ymm4,ymm9
913	and	eax,0x1fffffff
914
915	imul	rbx,QWORD[((16-128))+rsi]
916	add	r12,rbx
917	vpmuludq	ymm12,ymm12,ymm10
918	vmovd	xmm11,eax
919	vmovdqu	ymm0,YMMWORD[((-8+96-128))+rsi]
920	vpaddq	ymm1,ymm1,ymm12
921	vpmuludq	ymm13,ymm13,ymm10
922	vpbroadcastq	ymm11,xmm11
923	vmovdqu	ymm12,YMMWORD[((-8+128-128))+rsi]
924	vpaddq	ymm2,ymm2,ymm13
925	vpmuludq	ymm0,ymm0,ymm10
926	vmovdqu	ymm13,YMMWORD[((-8+160-128))+rsi]
927	vpaddq	ymm3,ymm3,ymm0
928	vpmuludq	ymm12,ymm12,ymm10
929	vmovdqu	ymm0,YMMWORD[((-8+192-128))+rsi]
930	vpaddq	ymm4,ymm4,ymm12
931	vpmuludq	ymm13,ymm13,ymm10
932	vmovdqu	ymm12,YMMWORD[((-8+224-128))+rsi]
933	vpaddq	ymm5,ymm5,ymm13
934	vpmuludq	ymm0,ymm0,ymm10
935	vmovdqu	ymm13,YMMWORD[((-8+256-128))+rsi]
936	vpaddq	ymm6,ymm6,ymm0
937	vpmuludq	ymm12,ymm12,ymm10
938	vmovdqu	ymm9,YMMWORD[((-8+288-128))+rsi]
939	vpaddq	ymm7,ymm7,ymm12
940	vpmuludq	ymm13,ymm13,ymm10
941	vpaddq	ymm8,ymm8,ymm13
942	vpmuludq	ymm9,ymm9,ymm10
943	vpbroadcastq	ymm10,QWORD[16+r13]
944
945	mov	rdx,rax
946	imul	rax,QWORD[((-128))+rcx]
947	add	r10,rax
948	vmovdqu	ymm0,YMMWORD[((-8+32-128))+rcx]
949	mov	rax,rdx
950	imul	rax,QWORD[((8-128))+rcx]
951	add	r11,rax
952	vmovdqu	ymm12,YMMWORD[((-8+64-128))+rcx]
953	shr	r10,29
954	imul	rdx,QWORD[((16-128))+rcx]
955	add	r12,rdx
956	add	r11,r10
957
958	vpmuludq	ymm0,ymm0,ymm11
959	vmovq	rbx,xmm10
960	vmovdqu	ymm13,YMMWORD[((-8+96-128))+rcx]
961	vpaddq	ymm1,ymm1,ymm0
962	vpmuludq	ymm12,ymm12,ymm11
963	vmovdqu	ymm0,YMMWORD[((-8+128-128))+rcx]
964	vpaddq	ymm2,ymm2,ymm12
965	vpmuludq	ymm13,ymm13,ymm11
966	vmovdqu	ymm12,YMMWORD[((-8+160-128))+rcx]
967	vpaddq	ymm3,ymm3,ymm13
968	vpmuludq	ymm0,ymm0,ymm11
969	vmovdqu	ymm13,YMMWORD[((-8+192-128))+rcx]
970	vpaddq	ymm4,ymm4,ymm0
971	vpmuludq	ymm12,ymm12,ymm11
972	vmovdqu	ymm0,YMMWORD[((-8+224-128))+rcx]
973	vpaddq	ymm5,ymm5,ymm12
974	vpmuludq	ymm13,ymm13,ymm11
975	vmovdqu	ymm12,YMMWORD[((-8+256-128))+rcx]
976	vpaddq	ymm6,ymm6,ymm13
977	vpmuludq	ymm0,ymm0,ymm11
978	vmovdqu	ymm13,YMMWORD[((-8+288-128))+rcx]
979	vpaddq	ymm7,ymm7,ymm0
980	vpmuludq	ymm12,ymm12,ymm11
981	vpaddq	ymm8,ymm8,ymm12
982	vpmuludq	ymm13,ymm13,ymm11
983	vpaddq	ymm9,ymm9,ymm13
984
985	vmovdqu	ymm0,YMMWORD[((-16+32-128))+rsi]
986	mov	rax,rbx
987	imul	rax,QWORD[((-128))+rsi]
988	add	rax,r11
989
990	vmovdqu	ymm12,YMMWORD[((-16+64-128))+rsi]
991	mov	r11,rax
992	imul	eax,r8d
993	and	eax,0x1fffffff
994
995	imul	rbx,QWORD[((8-128))+rsi]
996	add	r12,rbx
997	vpmuludq	ymm0,ymm0,ymm10
998	vmovd	xmm11,eax
999	vmovdqu	ymm13,YMMWORD[((-16+96-128))+rsi]
1000	vpaddq	ymm1,ymm1,ymm0
1001	vpmuludq	ymm12,ymm12,ymm10
1002	vpbroadcastq	ymm11,xmm11
1003	vmovdqu	ymm0,YMMWORD[((-16+128-128))+rsi]
1004	vpaddq	ymm2,ymm2,ymm12
1005	vpmuludq	ymm13,ymm13,ymm10
1006	vmovdqu	ymm12,YMMWORD[((-16+160-128))+rsi]
1007	vpaddq	ymm3,ymm3,ymm13
1008	vpmuludq	ymm0,ymm0,ymm10
1009	vmovdqu	ymm13,YMMWORD[((-16+192-128))+rsi]
1010	vpaddq	ymm4,ymm4,ymm0
1011	vpmuludq	ymm12,ymm12,ymm10
1012	vmovdqu	ymm0,YMMWORD[((-16+224-128))+rsi]
1013	vpaddq	ymm5,ymm5,ymm12
1014	vpmuludq	ymm13,ymm13,ymm10
1015	vmovdqu	ymm12,YMMWORD[((-16+256-128))+rsi]
1016	vpaddq	ymm6,ymm6,ymm13
1017	vpmuludq	ymm0,ymm0,ymm10
1018	vmovdqu	ymm13,YMMWORD[((-16+288-128))+rsi]
1019	vpaddq	ymm7,ymm7,ymm0
1020	vpmuludq	ymm12,ymm12,ymm10
1021	vpaddq	ymm8,ymm8,ymm12
1022	vpmuludq	ymm13,ymm13,ymm10
1023	vpbroadcastq	ymm10,QWORD[24+r13]
1024	vpaddq	ymm9,ymm9,ymm13
1025
1026	vmovdqu	ymm0,YMMWORD[((-16+32-128))+rcx]
1027	mov	rdx,rax
1028	imul	rax,QWORD[((-128))+rcx]
1029	add	r11,rax
1030	vmovdqu	ymm12,YMMWORD[((-16+64-128))+rcx]
1031	imul	rdx,QWORD[((8-128))+rcx]
1032	add	r12,rdx
1033	shr	r11,29
1034
1035	vpmuludq	ymm0,ymm0,ymm11
1036	vmovq	rbx,xmm10
1037	vmovdqu	ymm13,YMMWORD[((-16+96-128))+rcx]
1038	vpaddq	ymm1,ymm1,ymm0
1039	vpmuludq	ymm12,ymm12,ymm11
1040	vmovdqu	ymm0,YMMWORD[((-16+128-128))+rcx]
1041	vpaddq	ymm2,ymm2,ymm12
1042	vpmuludq	ymm13,ymm13,ymm11
1043	vmovdqu	ymm12,YMMWORD[((-16+160-128))+rcx]
1044	vpaddq	ymm3,ymm3,ymm13
1045	vpmuludq	ymm0,ymm0,ymm11
1046	vmovdqu	ymm13,YMMWORD[((-16+192-128))+rcx]
1047	vpaddq	ymm4,ymm4,ymm0
1048	vpmuludq	ymm12,ymm12,ymm11
1049	vmovdqu	ymm0,YMMWORD[((-16+224-128))+rcx]
1050	vpaddq	ymm5,ymm5,ymm12
1051	vpmuludq	ymm13,ymm13,ymm11
1052	vmovdqu	ymm12,YMMWORD[((-16+256-128))+rcx]
1053	vpaddq	ymm6,ymm6,ymm13
1054	vpmuludq	ymm0,ymm0,ymm11
1055	vmovdqu	ymm13,YMMWORD[((-16+288-128))+rcx]
1056	vpaddq	ymm7,ymm7,ymm0
1057	vpmuludq	ymm12,ymm12,ymm11
1058	vmovdqu	ymm0,YMMWORD[((-24+32-128))+rsi]
1059	vpaddq	ymm8,ymm8,ymm12
1060	vpmuludq	ymm13,ymm13,ymm11
1061	vmovdqu	ymm12,YMMWORD[((-24+64-128))+rsi]
1062	vpaddq	ymm9,ymm9,ymm13
1063
1064	add	r12,r11
1065	imul	rbx,QWORD[((-128))+rsi]
1066	add	r12,rbx
1067
1068	mov	rax,r12
1069	imul	eax,r8d
1070	and	eax,0x1fffffff
1071
1072	vpmuludq	ymm0,ymm0,ymm10
1073	vmovd	xmm11,eax
1074	vmovdqu	ymm13,YMMWORD[((-24+96-128))+rsi]
1075	vpaddq	ymm1,ymm1,ymm0
1076	vpmuludq	ymm12,ymm12,ymm10
1077	vpbroadcastq	ymm11,xmm11
1078	vmovdqu	ymm0,YMMWORD[((-24+128-128))+rsi]
1079	vpaddq	ymm2,ymm2,ymm12
1080	vpmuludq	ymm13,ymm13,ymm10
1081	vmovdqu	ymm12,YMMWORD[((-24+160-128))+rsi]
1082	vpaddq	ymm3,ymm3,ymm13
1083	vpmuludq	ymm0,ymm0,ymm10
1084	vmovdqu	ymm13,YMMWORD[((-24+192-128))+rsi]
1085	vpaddq	ymm4,ymm4,ymm0
1086	vpmuludq	ymm12,ymm12,ymm10
1087	vmovdqu	ymm0,YMMWORD[((-24+224-128))+rsi]
1088	vpaddq	ymm5,ymm5,ymm12
1089	vpmuludq	ymm13,ymm13,ymm10
1090	vmovdqu	ymm12,YMMWORD[((-24+256-128))+rsi]
1091	vpaddq	ymm6,ymm6,ymm13
1092	vpmuludq	ymm0,ymm0,ymm10
1093	vmovdqu	ymm13,YMMWORD[((-24+288-128))+rsi]
1094	vpaddq	ymm7,ymm7,ymm0
1095	vpmuludq	ymm12,ymm12,ymm10
1096	vpaddq	ymm8,ymm8,ymm12
1097	vpmuludq	ymm13,ymm13,ymm10
1098	vpbroadcastq	ymm10,QWORD[32+r13]
1099	vpaddq	ymm9,ymm9,ymm13
1100	add	r13,32
1101
1102	vmovdqu	ymm0,YMMWORD[((-24+32-128))+rcx]
1103	imul	rax,QWORD[((-128))+rcx]
1104	add	r12,rax
1105	shr	r12,29
1106
1107	vmovdqu	ymm12,YMMWORD[((-24+64-128))+rcx]
1108	vpmuludq	ymm0,ymm0,ymm11
1109	vmovq	rbx,xmm10
1110	vmovdqu	ymm13,YMMWORD[((-24+96-128))+rcx]
1111	vpaddq	ymm0,ymm1,ymm0
1112	vpmuludq	ymm12,ymm12,ymm11
1113	vmovdqu	YMMWORD[rsp],ymm0
1114	vpaddq	ymm1,ymm2,ymm12
1115	vmovdqu	ymm0,YMMWORD[((-24+128-128))+rcx]
1116	vpmuludq	ymm13,ymm13,ymm11
1117	vmovdqu	ymm12,YMMWORD[((-24+160-128))+rcx]
1118	vpaddq	ymm2,ymm3,ymm13
1119	vpmuludq	ymm0,ymm0,ymm11
1120	vmovdqu	ymm13,YMMWORD[((-24+192-128))+rcx]
1121	vpaddq	ymm3,ymm4,ymm0
1122	vpmuludq	ymm12,ymm12,ymm11
1123	vmovdqu	ymm0,YMMWORD[((-24+224-128))+rcx]
1124	vpaddq	ymm4,ymm5,ymm12
1125	vpmuludq	ymm13,ymm13,ymm11
1126	vmovdqu	ymm12,YMMWORD[((-24+256-128))+rcx]
1127	vpaddq	ymm5,ymm6,ymm13
1128	vpmuludq	ymm0,ymm0,ymm11
1129	vmovdqu	ymm13,YMMWORD[((-24+288-128))+rcx]
1130	mov	r9,r12
1131	vpaddq	ymm6,ymm7,ymm0
1132	vpmuludq	ymm12,ymm12,ymm11
1133	add	r9,QWORD[rsp]
1134	vpaddq	ymm7,ymm8,ymm12
1135	vpmuludq	ymm13,ymm13,ymm11
1136	vmovq	xmm12,r12
1137	vpaddq	ymm8,ymm9,ymm13
1138
1139	dec	r14d
1140	jnz	NEAR $L$oop_mul_1024
1141	vpaddq	ymm0,ymm12,YMMWORD[rsp]
1142
1143	vpsrlq	ymm12,ymm0,29
1144	vpand	ymm0,ymm0,ymm15
1145	vpsrlq	ymm13,ymm1,29
1146	vpand	ymm1,ymm1,ymm15
1147	vpsrlq	ymm10,ymm2,29
1148	vpermq	ymm12,ymm12,0x93
1149	vpand	ymm2,ymm2,ymm15
1150	vpsrlq	ymm11,ymm3,29
1151	vpermq	ymm13,ymm13,0x93
1152	vpand	ymm3,ymm3,ymm15
1153
1154	vpblendd	ymm9,ymm12,ymm14,3
1155	vpermq	ymm10,ymm10,0x93
1156	vpblendd	ymm12,ymm13,ymm12,3
1157	vpermq	ymm11,ymm11,0x93
1158	vpaddq	ymm0,ymm0,ymm9
1159	vpblendd	ymm13,ymm10,ymm13,3
1160	vpaddq	ymm1,ymm1,ymm12
1161	vpblendd	ymm10,ymm11,ymm10,3
1162	vpaddq	ymm2,ymm2,ymm13
1163	vpblendd	ymm11,ymm14,ymm11,3
1164	vpaddq	ymm3,ymm3,ymm10
1165	vpaddq	ymm4,ymm4,ymm11
1166
1167	vpsrlq	ymm12,ymm0,29
1168	vpand	ymm0,ymm0,ymm15
1169	vpsrlq	ymm13,ymm1,29
1170	vpand	ymm1,ymm1,ymm15
1171	vpsrlq	ymm10,ymm2,29
1172	vpermq	ymm12,ymm12,0x93
1173	vpand	ymm2,ymm2,ymm15
1174	vpsrlq	ymm11,ymm3,29
1175	vpermq	ymm13,ymm13,0x93
1176	vpand	ymm3,ymm3,ymm15
1177	vpermq	ymm10,ymm10,0x93
1178
1179	vpblendd	ymm9,ymm12,ymm14,3
1180	vpermq	ymm11,ymm11,0x93
1181	vpblendd	ymm12,ymm13,ymm12,3
1182	vpaddq	ymm0,ymm0,ymm9
1183	vpblendd	ymm13,ymm10,ymm13,3
1184	vpaddq	ymm1,ymm1,ymm12
1185	vpblendd	ymm10,ymm11,ymm10,3
1186	vpaddq	ymm2,ymm2,ymm13
1187	vpblendd	ymm11,ymm14,ymm11,3
1188	vpaddq	ymm3,ymm3,ymm10
1189	vpaddq	ymm4,ymm4,ymm11
1190
1191	vmovdqu	YMMWORD[(0-128)+rdi],ymm0
1192	vmovdqu	YMMWORD[(32-128)+rdi],ymm1
1193	vmovdqu	YMMWORD[(64-128)+rdi],ymm2
1194	vmovdqu	YMMWORD[(96-128)+rdi],ymm3
1195	vpsrlq	ymm12,ymm4,29
1196	vpand	ymm4,ymm4,ymm15
1197	vpsrlq	ymm13,ymm5,29
1198	vpand	ymm5,ymm5,ymm15
1199	vpsrlq	ymm10,ymm6,29
1200	vpermq	ymm12,ymm12,0x93
1201	vpand	ymm6,ymm6,ymm15
1202	vpsrlq	ymm11,ymm7,29
1203	vpermq	ymm13,ymm13,0x93
1204	vpand	ymm7,ymm7,ymm15
1205	vpsrlq	ymm0,ymm8,29
1206	vpermq	ymm10,ymm10,0x93
1207	vpand	ymm8,ymm8,ymm15
1208	vpermq	ymm11,ymm11,0x93
1209
1210	vpblendd	ymm9,ymm12,ymm14,3
1211	vpermq	ymm0,ymm0,0x93
1212	vpblendd	ymm12,ymm13,ymm12,3
1213	vpaddq	ymm4,ymm4,ymm9
1214	vpblendd	ymm13,ymm10,ymm13,3
1215	vpaddq	ymm5,ymm5,ymm12
1216	vpblendd	ymm10,ymm11,ymm10,3
1217	vpaddq	ymm6,ymm6,ymm13
1218	vpblendd	ymm11,ymm0,ymm11,3
1219	vpaddq	ymm7,ymm7,ymm10
1220	vpaddq	ymm8,ymm8,ymm11
1221
1222	vpsrlq	ymm12,ymm4,29
1223	vpand	ymm4,ymm4,ymm15
1224	vpsrlq	ymm13,ymm5,29
1225	vpand	ymm5,ymm5,ymm15
1226	vpsrlq	ymm10,ymm6,29
1227	vpermq	ymm12,ymm12,0x93
1228	vpand	ymm6,ymm6,ymm15
1229	vpsrlq	ymm11,ymm7,29
1230	vpermq	ymm13,ymm13,0x93
1231	vpand	ymm7,ymm7,ymm15
1232	vpsrlq	ymm0,ymm8,29
1233	vpermq	ymm10,ymm10,0x93
1234	vpand	ymm8,ymm8,ymm15
1235	vpermq	ymm11,ymm11,0x93
1236
1237	vpblendd	ymm9,ymm12,ymm14,3
1238	vpermq	ymm0,ymm0,0x93
1239	vpblendd	ymm12,ymm13,ymm12,3
1240	vpaddq	ymm4,ymm4,ymm9
1241	vpblendd	ymm13,ymm10,ymm13,3
1242	vpaddq	ymm5,ymm5,ymm12
1243	vpblendd	ymm10,ymm11,ymm10,3
1244	vpaddq	ymm6,ymm6,ymm13
1245	vpblendd	ymm11,ymm0,ymm11,3
1246	vpaddq	ymm7,ymm7,ymm10
1247	vpaddq	ymm8,ymm8,ymm11
1248
1249	vmovdqu	YMMWORD[(128-128)+rdi],ymm4
1250	vmovdqu	YMMWORD[(160-128)+rdi],ymm5
1251	vmovdqu	YMMWORD[(192-128)+rdi],ymm6
1252	vmovdqu	YMMWORD[(224-128)+rdi],ymm7
1253	vmovdqu	YMMWORD[(256-128)+rdi],ymm8
1254	vzeroupper
1255
1256	mov	rax,rbp
1257
1258$L$mul_1024_in_tail:
1259	movaps	xmm6,XMMWORD[((-216))+rax]
1260	movaps	xmm7,XMMWORD[((-200))+rax]
1261	movaps	xmm8,XMMWORD[((-184))+rax]
1262	movaps	xmm9,XMMWORD[((-168))+rax]
1263	movaps	xmm10,XMMWORD[((-152))+rax]
1264	movaps	xmm11,XMMWORD[((-136))+rax]
1265	movaps	xmm12,XMMWORD[((-120))+rax]
1266	movaps	xmm13,XMMWORD[((-104))+rax]
1267	movaps	xmm14,XMMWORD[((-88))+rax]
1268	movaps	xmm15,XMMWORD[((-72))+rax]
1269	mov	r15,QWORD[((-48))+rax]
1270
1271	mov	r14,QWORD[((-40))+rax]
1272
1273	mov	r13,QWORD[((-32))+rax]
1274
1275	mov	r12,QWORD[((-24))+rax]
1276
1277	mov	rbp,QWORD[((-16))+rax]
1278
1279	mov	rbx,QWORD[((-8))+rax]
1280
1281	lea	rsp,[rax]
1282
1283$L$mul_1024_epilogue:
1284	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
1285	mov	rsi,QWORD[16+rsp]
1286	DB	0F3h,0C3h		;repret
1287
1288$L$SEH_end_rsaz_1024_mul_avx2:
1289global	rsaz_1024_red2norm_avx2
1290
1291ALIGN	32
1292rsaz_1024_red2norm_avx2:
1293	sub	rdx,-128
1294	xor	rax,rax
1295	mov	r8,QWORD[((-128))+rdx]
1296	mov	r9,QWORD[((-120))+rdx]
1297	mov	r10,QWORD[((-112))+rdx]
1298	shl	r8,0
1299	shl	r9,29
1300	mov	r11,r10
1301	shl	r10,58
1302	shr	r11,6
1303	add	rax,r8
1304	add	rax,r9
1305	add	rax,r10
1306	adc	r11,0
1307	mov	QWORD[rcx],rax
1308	mov	rax,r11
1309	mov	r8,QWORD[((-104))+rdx]
1310	mov	r9,QWORD[((-96))+rdx]
1311	shl	r8,23
1312	mov	r10,r9
1313	shl	r9,52
1314	shr	r10,12
1315	add	rax,r8
1316	add	rax,r9
1317	adc	r10,0
1318	mov	QWORD[8+rcx],rax
1319	mov	rax,r10
1320	mov	r11,QWORD[((-88))+rdx]
1321	mov	r8,QWORD[((-80))+rdx]
1322	shl	r11,17
1323	mov	r9,r8
1324	shl	r8,46
1325	shr	r9,18
1326	add	rax,r11
1327	add	rax,r8
1328	adc	r9,0
1329	mov	QWORD[16+rcx],rax
1330	mov	rax,r9
1331	mov	r10,QWORD[((-72))+rdx]
1332	mov	r11,QWORD[((-64))+rdx]
1333	shl	r10,11
1334	mov	r8,r11
1335	shl	r11,40
1336	shr	r8,24
1337	add	rax,r10
1338	add	rax,r11
1339	adc	r8,0
1340	mov	QWORD[24+rcx],rax
1341	mov	rax,r8
1342	mov	r9,QWORD[((-56))+rdx]
1343	mov	r10,QWORD[((-48))+rdx]
1344	mov	r11,QWORD[((-40))+rdx]
1345	shl	r9,5
1346	shl	r10,34
1347	mov	r8,r11
1348	shl	r11,63
1349	shr	r8,1
1350	add	rax,r9
1351	add	rax,r10
1352	add	rax,r11
1353	adc	r8,0
1354	mov	QWORD[32+rcx],rax
1355	mov	rax,r8
1356	mov	r9,QWORD[((-32))+rdx]
1357	mov	r10,QWORD[((-24))+rdx]
1358	shl	r9,28
1359	mov	r11,r10
1360	shl	r10,57
1361	shr	r11,7
1362	add	rax,r9
1363	add	rax,r10
1364	adc	r11,0
1365	mov	QWORD[40+rcx],rax
1366	mov	rax,r11
1367	mov	r8,QWORD[((-16))+rdx]
1368	mov	r9,QWORD[((-8))+rdx]
1369	shl	r8,22
1370	mov	r10,r9
1371	shl	r9,51
1372	shr	r10,13
1373	add	rax,r8
1374	add	rax,r9
1375	adc	r10,0
1376	mov	QWORD[48+rcx],rax
1377	mov	rax,r10
1378	mov	r11,QWORD[rdx]
1379	mov	r8,QWORD[8+rdx]
1380	shl	r11,16
1381	mov	r9,r8
1382	shl	r8,45
1383	shr	r9,19
1384	add	rax,r11
1385	add	rax,r8
1386	adc	r9,0
1387	mov	QWORD[56+rcx],rax
1388	mov	rax,r9
1389	mov	r10,QWORD[16+rdx]
1390	mov	r11,QWORD[24+rdx]
1391	shl	r10,10
1392	mov	r8,r11
1393	shl	r11,39
1394	shr	r8,25
1395	add	rax,r10
1396	add	rax,r11
1397	adc	r8,0
1398	mov	QWORD[64+rcx],rax
1399	mov	rax,r8
1400	mov	r9,QWORD[32+rdx]
1401	mov	r10,QWORD[40+rdx]
1402	mov	r11,QWORD[48+rdx]
1403	shl	r9,4
1404	shl	r10,33
1405	mov	r8,r11
1406	shl	r11,62
1407	shr	r8,2
1408	add	rax,r9
1409	add	rax,r10
1410	add	rax,r11
1411	adc	r8,0
1412	mov	QWORD[72+rcx],rax
1413	mov	rax,r8
1414	mov	r9,QWORD[56+rdx]
1415	mov	r10,QWORD[64+rdx]
1416	shl	r9,27
1417	mov	r11,r10
1418	shl	r10,56
1419	shr	r11,8
1420	add	rax,r9
1421	add	rax,r10
1422	adc	r11,0
1423	mov	QWORD[80+rcx],rax
1424	mov	rax,r11
1425	mov	r8,QWORD[72+rdx]
1426	mov	r9,QWORD[80+rdx]
1427	shl	r8,21
1428	mov	r10,r9
1429	shl	r9,50
1430	shr	r10,14
1431	add	rax,r8
1432	add	rax,r9
1433	adc	r10,0
1434	mov	QWORD[88+rcx],rax
1435	mov	rax,r10
1436	mov	r11,QWORD[88+rdx]
1437	mov	r8,QWORD[96+rdx]
1438	shl	r11,15
1439	mov	r9,r8
1440	shl	r8,44
1441	shr	r9,20
1442	add	rax,r11
1443	add	rax,r8
1444	adc	r9,0
1445	mov	QWORD[96+rcx],rax
1446	mov	rax,r9
1447	mov	r10,QWORD[104+rdx]
1448	mov	r11,QWORD[112+rdx]
1449	shl	r10,9
1450	mov	r8,r11
1451	shl	r11,38
1452	shr	r8,26
1453	add	rax,r10
1454	add	rax,r11
1455	adc	r8,0
1456	mov	QWORD[104+rcx],rax
1457	mov	rax,r8
1458	mov	r9,QWORD[120+rdx]
1459	mov	r10,QWORD[128+rdx]
1460	mov	r11,QWORD[136+rdx]
1461	shl	r9,3
1462	shl	r10,32
1463	mov	r8,r11
1464	shl	r11,61
1465	shr	r8,3
1466	add	rax,r9
1467	add	rax,r10
1468	add	rax,r11
1469	adc	r8,0
1470	mov	QWORD[112+rcx],rax
1471	mov	rax,r8
1472	mov	r9,QWORD[144+rdx]
1473	mov	r10,QWORD[152+rdx]
1474	shl	r9,26
1475	mov	r11,r10
1476	shl	r10,55
1477	shr	r11,9
1478	add	rax,r9
1479	add	rax,r10
1480	adc	r11,0
1481	mov	QWORD[120+rcx],rax
1482	mov	rax,r11
1483	DB	0F3h,0C3h		;repret
1484
1485
1486global	rsaz_1024_norm2red_avx2
1487
1488ALIGN	32
1489rsaz_1024_norm2red_avx2:
1490	sub	rcx,-128
1491	mov	r8,QWORD[rdx]
1492	mov	eax,0x1fffffff
1493	mov	r9,QWORD[8+rdx]
1494	mov	r11,r8
1495	shr	r11,0
1496	and	r11,rax
1497	mov	QWORD[((-128))+rcx],r11
1498	mov	r10,r8
1499	shr	r10,29
1500	and	r10,rax
1501	mov	QWORD[((-120))+rcx],r10
1502	shrd	r8,r9,58
1503	and	r8,rax
1504	mov	QWORD[((-112))+rcx],r8
1505	mov	r10,QWORD[16+rdx]
1506	mov	r8,r9
1507	shr	r8,23
1508	and	r8,rax
1509	mov	QWORD[((-104))+rcx],r8
1510	shrd	r9,r10,52
1511	and	r9,rax
1512	mov	QWORD[((-96))+rcx],r9
1513	mov	r11,QWORD[24+rdx]
1514	mov	r9,r10
1515	shr	r9,17
1516	and	r9,rax
1517	mov	QWORD[((-88))+rcx],r9
1518	shrd	r10,r11,46
1519	and	r10,rax
1520	mov	QWORD[((-80))+rcx],r10
1521	mov	r8,QWORD[32+rdx]
1522	mov	r10,r11
1523	shr	r10,11
1524	and	r10,rax
1525	mov	QWORD[((-72))+rcx],r10
1526	shrd	r11,r8,40
1527	and	r11,rax
1528	mov	QWORD[((-64))+rcx],r11
1529	mov	r9,QWORD[40+rdx]
1530	mov	r11,r8
1531	shr	r11,5
1532	and	r11,rax
1533	mov	QWORD[((-56))+rcx],r11
1534	mov	r10,r8
1535	shr	r10,34
1536	and	r10,rax
1537	mov	QWORD[((-48))+rcx],r10
1538	shrd	r8,r9,63
1539	and	r8,rax
1540	mov	QWORD[((-40))+rcx],r8
1541	mov	r10,QWORD[48+rdx]
1542	mov	r8,r9
1543	shr	r8,28
1544	and	r8,rax
1545	mov	QWORD[((-32))+rcx],r8
1546	shrd	r9,r10,57
1547	and	r9,rax
1548	mov	QWORD[((-24))+rcx],r9
1549	mov	r11,QWORD[56+rdx]
1550	mov	r9,r10
1551	shr	r9,22
1552	and	r9,rax
1553	mov	QWORD[((-16))+rcx],r9
1554	shrd	r10,r11,51
1555	and	r10,rax
1556	mov	QWORD[((-8))+rcx],r10
1557	mov	r8,QWORD[64+rdx]
1558	mov	r10,r11
1559	shr	r10,16
1560	and	r10,rax
1561	mov	QWORD[rcx],r10
1562	shrd	r11,r8,45
1563	and	r11,rax
1564	mov	QWORD[8+rcx],r11
1565	mov	r9,QWORD[72+rdx]
1566	mov	r11,r8
1567	shr	r11,10
1568	and	r11,rax
1569	mov	QWORD[16+rcx],r11
1570	shrd	r8,r9,39
1571	and	r8,rax
1572	mov	QWORD[24+rcx],r8
1573	mov	r10,QWORD[80+rdx]
1574	mov	r8,r9
1575	shr	r8,4
1576	and	r8,rax
1577	mov	QWORD[32+rcx],r8
1578	mov	r11,r9
1579	shr	r11,33
1580	and	r11,rax
1581	mov	QWORD[40+rcx],r11
1582	shrd	r9,r10,62
1583	and	r9,rax
1584	mov	QWORD[48+rcx],r9
1585	mov	r11,QWORD[88+rdx]
1586	mov	r9,r10
1587	shr	r9,27
1588	and	r9,rax
1589	mov	QWORD[56+rcx],r9
1590	shrd	r10,r11,56
1591	and	r10,rax
1592	mov	QWORD[64+rcx],r10
1593	mov	r8,QWORD[96+rdx]
1594	mov	r10,r11
1595	shr	r10,21
1596	and	r10,rax
1597	mov	QWORD[72+rcx],r10
1598	shrd	r11,r8,50
1599	and	r11,rax
1600	mov	QWORD[80+rcx],r11
1601	mov	r9,QWORD[104+rdx]
1602	mov	r11,r8
1603	shr	r11,15
1604	and	r11,rax
1605	mov	QWORD[88+rcx],r11
1606	shrd	r8,r9,44
1607	and	r8,rax
1608	mov	QWORD[96+rcx],r8
1609	mov	r10,QWORD[112+rdx]
1610	mov	r8,r9
1611	shr	r8,9
1612	and	r8,rax
1613	mov	QWORD[104+rcx],r8
1614	shrd	r9,r10,38
1615	and	r9,rax
1616	mov	QWORD[112+rcx],r9
1617	mov	r11,QWORD[120+rdx]
1618	mov	r9,r10
1619	shr	r9,3
1620	and	r9,rax
1621	mov	QWORD[120+rcx],r9
1622	mov	r8,r10
1623	shr	r8,32
1624	and	r8,rax
1625	mov	QWORD[128+rcx],r8
1626	shrd	r10,r11,61
1627	and	r10,rax
1628	mov	QWORD[136+rcx],r10
1629	xor	r8,r8
1630	mov	r10,r11
1631	shr	r10,26
1632	and	r10,rax
1633	mov	QWORD[144+rcx],r10
1634	shrd	r11,r8,55
1635	and	r11,rax
1636	mov	QWORD[152+rcx],r11
1637	mov	QWORD[160+rcx],r8
1638	mov	QWORD[168+rcx],r8
1639	mov	QWORD[176+rcx],r8
1640	mov	QWORD[184+rcx],r8
1641	DB	0F3h,0C3h		;repret
1642
1643global	rsaz_1024_scatter5_avx2
1644
1645ALIGN	32
1646rsaz_1024_scatter5_avx2:
1647	vzeroupper
1648	vmovdqu	ymm5,YMMWORD[$L$scatter_permd]
1649	shl	r8d,4
1650	lea	rcx,[r8*1+rcx]
1651	mov	eax,9
1652	jmp	NEAR $L$oop_scatter_1024
1653
1654ALIGN	32
1655$L$oop_scatter_1024:
1656	vmovdqu	ymm0,YMMWORD[rdx]
1657	lea	rdx,[32+rdx]
1658	vpermd	ymm0,ymm5,ymm0
1659	vmovdqu	XMMWORD[rcx],xmm0
1660	lea	rcx,[512+rcx]
1661	dec	eax
1662	jnz	NEAR $L$oop_scatter_1024
1663
1664	vzeroupper
1665	DB	0F3h,0C3h		;repret
1666
1667
1668global	rsaz_1024_gather5_avx2
1669
1670ALIGN	32
1671rsaz_1024_gather5_avx2:
1672
1673	vzeroupper
1674	mov	r11,rsp
1675
1676	lea	rax,[((-136))+rsp]
1677$L$SEH_begin_rsaz_1024_gather5:
1678
1679DB	0x48,0x8d,0x60,0xe0
1680DB	0xc5,0xf8,0x29,0x70,0xe0
1681DB	0xc5,0xf8,0x29,0x78,0xf0
1682DB	0xc5,0x78,0x29,0x40,0x00
1683DB	0xc5,0x78,0x29,0x48,0x10
1684DB	0xc5,0x78,0x29,0x50,0x20
1685DB	0xc5,0x78,0x29,0x58,0x30
1686DB	0xc5,0x78,0x29,0x60,0x40
1687DB	0xc5,0x78,0x29,0x68,0x50
1688DB	0xc5,0x78,0x29,0x70,0x60
1689DB	0xc5,0x78,0x29,0x78,0x70
1690	lea	rsp,[((-256))+rsp]
1691	and	rsp,-32
1692	lea	r10,[$L$inc]
1693	lea	rax,[((-128))+rsp]
1694
1695	vmovd	xmm4,r8d
1696	vmovdqa	ymm0,YMMWORD[r10]
1697	vmovdqa	ymm1,YMMWORD[32+r10]
1698	vmovdqa	ymm5,YMMWORD[64+r10]
1699	vpbroadcastd	ymm4,xmm4
1700
1701	vpaddd	ymm2,ymm0,ymm5
1702	vpcmpeqd	ymm0,ymm0,ymm4
1703	vpaddd	ymm3,ymm1,ymm5
1704	vpcmpeqd	ymm1,ymm1,ymm4
1705	vmovdqa	YMMWORD[(0+128)+rax],ymm0
1706	vpaddd	ymm0,ymm2,ymm5
1707	vpcmpeqd	ymm2,ymm2,ymm4
1708	vmovdqa	YMMWORD[(32+128)+rax],ymm1
1709	vpaddd	ymm1,ymm3,ymm5
1710	vpcmpeqd	ymm3,ymm3,ymm4
1711	vmovdqa	YMMWORD[(64+128)+rax],ymm2
1712	vpaddd	ymm2,ymm0,ymm5
1713	vpcmpeqd	ymm0,ymm0,ymm4
1714	vmovdqa	YMMWORD[(96+128)+rax],ymm3
1715	vpaddd	ymm3,ymm1,ymm5
1716	vpcmpeqd	ymm1,ymm1,ymm4
1717	vmovdqa	YMMWORD[(128+128)+rax],ymm0
1718	vpaddd	ymm8,ymm2,ymm5
1719	vpcmpeqd	ymm2,ymm2,ymm4
1720	vmovdqa	YMMWORD[(160+128)+rax],ymm1
1721	vpaddd	ymm9,ymm3,ymm5
1722	vpcmpeqd	ymm3,ymm3,ymm4
1723	vmovdqa	YMMWORD[(192+128)+rax],ymm2
1724	vpaddd	ymm10,ymm8,ymm5
1725	vpcmpeqd	ymm8,ymm8,ymm4
1726	vmovdqa	YMMWORD[(224+128)+rax],ymm3
1727	vpaddd	ymm11,ymm9,ymm5
1728	vpcmpeqd	ymm9,ymm9,ymm4
1729	vpaddd	ymm12,ymm10,ymm5
1730	vpcmpeqd	ymm10,ymm10,ymm4
1731	vpaddd	ymm13,ymm11,ymm5
1732	vpcmpeqd	ymm11,ymm11,ymm4
1733	vpaddd	ymm14,ymm12,ymm5
1734	vpcmpeqd	ymm12,ymm12,ymm4
1735	vpaddd	ymm15,ymm13,ymm5
1736	vpcmpeqd	ymm13,ymm13,ymm4
1737	vpcmpeqd	ymm14,ymm14,ymm4
1738	vpcmpeqd	ymm15,ymm15,ymm4
1739
1740	vmovdqa	ymm7,YMMWORD[((-32))+r10]
1741	lea	rdx,[128+rdx]
1742	mov	r8d,9
1743
1744$L$oop_gather_1024:
1745	vmovdqa	ymm0,YMMWORD[((0-128))+rdx]
1746	vmovdqa	ymm1,YMMWORD[((32-128))+rdx]
1747	vmovdqa	ymm2,YMMWORD[((64-128))+rdx]
1748	vmovdqa	ymm3,YMMWORD[((96-128))+rdx]
1749	vpand	ymm0,ymm0,YMMWORD[((0+128))+rax]
1750	vpand	ymm1,ymm1,YMMWORD[((32+128))+rax]
1751	vpand	ymm2,ymm2,YMMWORD[((64+128))+rax]
1752	vpor	ymm4,ymm1,ymm0
1753	vpand	ymm3,ymm3,YMMWORD[((96+128))+rax]
1754	vmovdqa	ymm0,YMMWORD[((128-128))+rdx]
1755	vmovdqa	ymm1,YMMWORD[((160-128))+rdx]
1756	vpor	ymm5,ymm3,ymm2
1757	vmovdqa	ymm2,YMMWORD[((192-128))+rdx]
1758	vmovdqa	ymm3,YMMWORD[((224-128))+rdx]
1759	vpand	ymm0,ymm0,YMMWORD[((128+128))+rax]
1760	vpand	ymm1,ymm1,YMMWORD[((160+128))+rax]
1761	vpand	ymm2,ymm2,YMMWORD[((192+128))+rax]
1762	vpor	ymm4,ymm4,ymm0
1763	vpand	ymm3,ymm3,YMMWORD[((224+128))+rax]
1764	vpand	ymm0,ymm8,YMMWORD[((256-128))+rdx]
1765	vpor	ymm5,ymm5,ymm1
1766	vpand	ymm1,ymm9,YMMWORD[((288-128))+rdx]
1767	vpor	ymm4,ymm4,ymm2
1768	vpand	ymm2,ymm10,YMMWORD[((320-128))+rdx]
1769	vpor	ymm5,ymm5,ymm3
1770	vpand	ymm3,ymm11,YMMWORD[((352-128))+rdx]
1771	vpor	ymm4,ymm4,ymm0
1772	vpand	ymm0,ymm12,YMMWORD[((384-128))+rdx]
1773	vpor	ymm5,ymm5,ymm1
1774	vpand	ymm1,ymm13,YMMWORD[((416-128))+rdx]
1775	vpor	ymm4,ymm4,ymm2
1776	vpand	ymm2,ymm14,YMMWORD[((448-128))+rdx]
1777	vpor	ymm5,ymm5,ymm3
1778	vpand	ymm3,ymm15,YMMWORD[((480-128))+rdx]
1779	lea	rdx,[512+rdx]
1780	vpor	ymm4,ymm4,ymm0
1781	vpor	ymm5,ymm5,ymm1
1782	vpor	ymm4,ymm4,ymm2
1783	vpor	ymm5,ymm5,ymm3
1784
1785	vpor	ymm4,ymm4,ymm5
1786	vextracti128	xmm5,ymm4,1
1787	vpor	xmm5,xmm5,xmm4
1788	vpermd	ymm5,ymm7,ymm5
1789	vmovdqu	YMMWORD[rcx],ymm5
1790	lea	rcx,[32+rcx]
1791	dec	r8d
1792	jnz	NEAR $L$oop_gather_1024
1793
1794	vpxor	ymm0,ymm0,ymm0
1795	vmovdqu	YMMWORD[rcx],ymm0
1796	vzeroupper
1797	movaps	xmm6,XMMWORD[((-168))+r11]
1798	movaps	xmm7,XMMWORD[((-152))+r11]
1799	movaps	xmm8,XMMWORD[((-136))+r11]
1800	movaps	xmm9,XMMWORD[((-120))+r11]
1801	movaps	xmm10,XMMWORD[((-104))+r11]
1802	movaps	xmm11,XMMWORD[((-88))+r11]
1803	movaps	xmm12,XMMWORD[((-72))+r11]
1804	movaps	xmm13,XMMWORD[((-56))+r11]
1805	movaps	xmm14,XMMWORD[((-40))+r11]
1806	movaps	xmm15,XMMWORD[((-24))+r11]
1807	lea	rsp,[r11]
1808
1809	DB	0F3h,0C3h		;repret
1810
1811$L$SEH_end_rsaz_1024_gather5:
1812
1813EXTERN	OPENSSL_ia32cap_P
1814global	rsaz_avx2_eligible
1815
1816ALIGN	32
1817rsaz_avx2_eligible:
1818	lea	rax,[OPENSSL_ia32cap_P]
1819	mov	eax,DWORD[8+rax]
1820	and	eax,32
1821	shr	eax,5
1822	DB	0F3h,0C3h		;repret
1823
1824
1825ALIGN	64
1826$L$and_mask:
1827	DQ	0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff
1828$L$scatter_permd:
1829	DD	0,2,4,6,7,7,7,7
1830$L$gather_permd:
1831	DD	0,7,1,7,2,7,3,7
1832$L$inc:
1833	DD	0,0,0,0,1,1,1,1
1834	DD	2,2,2,2,3,3,3,3
1835	DD	4,4,4,4,4,4,4,4
1836ALIGN	64
1837EXTERN	__imp_RtlVirtualUnwind
1838
1839ALIGN	16
1840rsaz_se_handler:
1841	push	rsi
1842	push	rdi
1843	push	rbx
1844	push	rbp
1845	push	r12
1846	push	r13
1847	push	r14
1848	push	r15
1849	pushfq
1850	sub	rsp,64
1851
1852	mov	rax,QWORD[120+r8]
1853	mov	rbx,QWORD[248+r8]
1854
1855	mov	rsi,QWORD[8+r9]
1856	mov	r11,QWORD[56+r9]
1857
1858	mov	r10d,DWORD[r11]
1859	lea	r10,[r10*1+rsi]
1860	cmp	rbx,r10
1861	jb	NEAR $L$common_seh_tail
1862
1863	mov	r10d,DWORD[4+r11]
1864	lea	r10,[r10*1+rsi]
1865	cmp	rbx,r10
1866	jae	NEAR $L$common_seh_tail
1867
1868	mov	rbp,QWORD[160+r8]
1869
1870	mov	r10d,DWORD[8+r11]
1871	lea	r10,[r10*1+rsi]
1872	cmp	rbx,r10
1873	cmovc	rax,rbp
1874
1875	mov	r15,QWORD[((-48))+rax]
1876	mov	r14,QWORD[((-40))+rax]
1877	mov	r13,QWORD[((-32))+rax]
1878	mov	r12,QWORD[((-24))+rax]
1879	mov	rbp,QWORD[((-16))+rax]
1880	mov	rbx,QWORD[((-8))+rax]
1881	mov	QWORD[240+r8],r15
1882	mov	QWORD[232+r8],r14
1883	mov	QWORD[224+r8],r13
1884	mov	QWORD[216+r8],r12
1885	mov	QWORD[160+r8],rbp
1886	mov	QWORD[144+r8],rbx
1887
1888	lea	rsi,[((-216))+rax]
1889	lea	rdi,[512+r8]
1890	mov	ecx,20
1891	DD	0xa548f3fc
1892
1893$L$common_seh_tail:
1894	mov	rdi,QWORD[8+rax]
1895	mov	rsi,QWORD[16+rax]
1896	mov	QWORD[152+r8],rax
1897	mov	QWORD[168+r8],rsi
1898	mov	QWORD[176+r8],rdi
1899
1900	mov	rdi,QWORD[40+r9]
1901	mov	rsi,r8
1902	mov	ecx,154
1903	DD	0xa548f3fc
1904
1905	mov	rsi,r9
1906	xor	rcx,rcx
1907	mov	rdx,QWORD[8+rsi]
1908	mov	r8,QWORD[rsi]
1909	mov	r9,QWORD[16+rsi]
1910	mov	r10,QWORD[40+rsi]
1911	lea	r11,[56+rsi]
1912	lea	r12,[24+rsi]
1913	mov	QWORD[32+rsp],r10
1914	mov	QWORD[40+rsp],r11
1915	mov	QWORD[48+rsp],r12
1916	mov	QWORD[56+rsp],rcx
1917	call	QWORD[__imp_RtlVirtualUnwind]
1918
1919	mov	eax,1
1920	add	rsp,64
1921	popfq
1922	pop	r15
1923	pop	r14
1924	pop	r13
1925	pop	r12
1926	pop	rbp
1927	pop	rbx
1928	pop	rdi
1929	pop	rsi
1930	DB	0F3h,0C3h		;repret
1931
1932
1933section	.pdata rdata align=4
1934ALIGN	4
1935	DD	$L$SEH_begin_rsaz_1024_sqr_avx2 wrt ..imagebase
1936	DD	$L$SEH_end_rsaz_1024_sqr_avx2 wrt ..imagebase
1937	DD	$L$SEH_info_rsaz_1024_sqr_avx2 wrt ..imagebase
1938
1939	DD	$L$SEH_begin_rsaz_1024_mul_avx2 wrt ..imagebase
1940	DD	$L$SEH_end_rsaz_1024_mul_avx2 wrt ..imagebase
1941	DD	$L$SEH_info_rsaz_1024_mul_avx2 wrt ..imagebase
1942
1943	DD	$L$SEH_begin_rsaz_1024_gather5 wrt ..imagebase
1944	DD	$L$SEH_end_rsaz_1024_gather5 wrt ..imagebase
1945	DD	$L$SEH_info_rsaz_1024_gather5 wrt ..imagebase
1946section	.xdata rdata align=8
1947ALIGN	8
1948$L$SEH_info_rsaz_1024_sqr_avx2:
1949DB	9,0,0,0
1950	DD	rsaz_se_handler wrt ..imagebase
1951	DD	$L$sqr_1024_body wrt ..imagebase,$L$sqr_1024_epilogue wrt ..imagebase,$L$sqr_1024_in_tail wrt ..imagebase
1952	DD	0
1953$L$SEH_info_rsaz_1024_mul_avx2:
1954DB	9,0,0,0
1955	DD	rsaz_se_handler wrt ..imagebase
1956	DD	$L$mul_1024_body wrt ..imagebase,$L$mul_1024_epilogue wrt ..imagebase,$L$mul_1024_in_tail wrt ..imagebase
1957	DD	0
1958$L$SEH_info_rsaz_1024_gather5:
1959DB	0x01,0x36,0x17,0x0b
1960DB	0x36,0xf8,0x09,0x00
1961DB	0x31,0xe8,0x08,0x00
1962DB	0x2c,0xd8,0x07,0x00
1963DB	0x27,0xc8,0x06,0x00
1964DB	0x22,0xb8,0x05,0x00
1965DB	0x1d,0xa8,0x04,0x00
1966DB	0x18,0x98,0x03,0x00
1967DB	0x13,0x88,0x02,0x00
1968DB	0x0e,0x78,0x01,0x00
1969DB	0x09,0x68,0x00,0x00
1970DB	0x04,0x01,0x15,0x00
1971DB	0x00,0xb3,0x00,0x00
1972