1/*
2 * Copyright 2012 pooler@litecoinpool.org
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.  See COPYING for more details.
8 */
9
10#include "cpuminer-config.h"
11
12#if defined(USE_ASM) && defined(__arm__) && defined(__APCS_32__)
13
14.macro sha256_k
15	.align 2
16	.long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
17	.long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
18	.long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
19	.long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
20	.long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
21	.long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
22	.long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
23	.long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
24	.long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
25	.long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
26	.long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
27	.long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
28	.long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
29	.long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
30	.long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
31	.long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
32.endm
33
34.macro sha256_extend_doubleround_core i, rw, ra, rb, ry, rz
35	mov	r12, \ry, ror #17
36	add	r11, r11, \ra
37	eor	r12, r12, \ry, ror #19
38	mov	\ra, lr, ror #7
39	eor	r12, r12, \ry, lsr #10
40	eor	\ra, \ra, lr, ror #18
41	add	r12, r12, r11
42	ldr	r11, [\rw, #(\i+2)*4]
43	eor	\ra, \ra, lr, lsr #3
44	add	\ra, \ra, r12
45
46	mov	r12, \rz, ror #17
47	str	\ra, [\rw, #(\i+16)*4]
48	add	lr, lr, \rb
49	eor	r12, r12, \rz, ror #19
50	mov	\rb, r11, ror #7
51	eor	r12, r12, \rz, lsr #10
52	eor	\rb, \rb, r11, ror #18
53	add	lr, lr, r12
54	eor	\rb, \rb, r11, lsr #3
55	add	\rb, \rb, lr
56.endm
57
58.macro sha256_extend_doubleround_head i, rw, ra, rb, ry, rz
59	ldr	lr, [\rw, #(\i+1)*4]
60	sha256_extend_doubleround_core \i, \rw, \ra, \rb, \ry, \rz
61	ldr	lr, [\rw, #(\i+3)*4]
62.endm
63
64.macro sha256_extend_doubleround_body i, rw, ra, rb, ry, rz
65	str	\rz, [\rw, #(\i+15)*4]
66	sha256_extend_doubleround_core \i, \rw, \ra, \rb, \ry, \rz
67	ldr	lr, [\rw, #(\i+3)*4]
68.endm
69
70.macro sha256_extend_doubleround_foot i, rw, ra, rb, ry, rz
71	str	\rz, [\rw, #(\i+15)*4]
72	sha256_extend_doubleround_core \i, \rw, \ra, \rb, \ry, \rz
73	str	\rb, [\rw, #(\i+17)*4]
74.endm
75
76.macro sha256_main_round i, ka, rw, ra, rb, rc, rd, re, rf, rg, rh
77	ldr	r12, [\rw, #(\i)*4]
78	and	r3, \rf, \re
79	bic	lr, \rg, \re
80	orr	lr, lr, r3
81	ldr	r3, \ka + (\i)*4
82	add	\rh, \rh, lr
83	eor	lr, \re, \re, ror #5
84	add	\rh, \rh, r12
85	eor	lr, lr, \re, ror #19
86	add	\rh, \rh, r3
87	eor	r3, \ra, \rb
88	add	\rh, \rh, lr, ror #6
89
90	and	r3, r3, \rc
91	eor	r12, \ra, \ra, ror #11
92	and	lr, \ra, \rb
93	eor	r12, r12, \ra, ror #20
94	eor	lr, lr, r3
95	add	r3, \rh, lr
96	add	\rh, \rh, \rd
97	add	\rd, r3, r12, ror #2
98.endm
99
100.macro sha256_main_quadround i, ka, rw
101	sha256_main_round \i+0, \ka, \rw, r4, r5, r6, r7, r8, r9, r10, r11
102	sha256_main_round \i+1, \ka, \rw, r7, r4, r5, r6, r11, r8, r9, r10
103	sha256_main_round \i+2, \ka, \rw, r6, r7, r4, r5, r10, r11, r8, r9
104	sha256_main_round \i+3, \ka, \rw, r5, r6, r7, r4, r9, r10, r11, r8
105.endm
106
107
108	.text
109	.code 32
110	.align 2
111	.globl sha256_transform
112	.globl _sha256_transform
113#ifdef __ELF__
114	.type sha256_transform, %function
115#endif
116sha256_transform:
117_sha256_transform:
118	stmfd	sp!, {r4-r11, lr}
119	cmp	r2, #0
120	sub	sp, sp, #64*4
121	bne	sha256_transform_swap
122
123	ldmia	r1!, {r4-r11}
124	stmia	sp, {r4-r11}
125	add	r3, sp, #8*4
126	ldmia	r1, {r4-r11}
127	stmia	r3, {r4-r11}
128	b	sha256_transform_extend
129
130.macro bswap rd, rn
131	eor	r12, \rn, \rn, ror #16
132	bic	r12, r12, #0x00ff0000
133	mov	\rd, \rn, ror #8
134	eor	\rd, \rd, r12, lsr #8
135.endm
136
137sha256_transform_swap:
138	ldmia	r1!, {r4-r11}
139	bswap	r4, r4
140	bswap	r5, r5
141	bswap	r6, r6
142	bswap	r7, r7
143	bswap	r8, r8
144	bswap	r9, r9
145	bswap	r10, r10
146	bswap	r11, r11
147	stmia	sp, {r4-r11}
148	add	r3, sp, #8*4
149	ldmia	r1, {r4-r11}
150	bswap	r4, r4
151	bswap	r5, r5
152	bswap	r6, r6
153	bswap	r7, r7
154	bswap	r8, r8
155	bswap	r9, r9
156	bswap	r10, r10
157	bswap	r11, r11
158	stmia	r3, {r4-r11}
159
160sha256_transform_extend:
161	add	r12, sp, #9*4
162	ldr	r11, [sp, #0*4]
163	ldmia	r12, {r4-r10}
164	sha256_extend_doubleround_head  0, sp, r4, r5, r9, r10
165	sha256_extend_doubleround_body  2, sp, r6, r7, r4, r5
166	sha256_extend_doubleround_body  4, sp, r8, r9, r6, r7
167	sha256_extend_doubleround_body  6, sp, r10, r4, r8, r9
168	sha256_extend_doubleround_body  8, sp, r5, r6, r10, r4
169	sha256_extend_doubleround_body 10, sp, r7, r8, r5, r6
170	sha256_extend_doubleround_body 12, sp, r9, r10, r7, r8
171	sha256_extend_doubleround_body 14, sp, r4, r5, r9, r10
172	sha256_extend_doubleround_body 16, sp, r6, r7, r4, r5
173	sha256_extend_doubleround_body 18, sp, r8, r9, r6, r7
174	sha256_extend_doubleround_body 20, sp, r10, r4, r8, r9
175	sha256_extend_doubleround_body 22, sp, r5, r6, r10, r4
176	sha256_extend_doubleround_body 24, sp, r7, r8, r5, r6
177	sha256_extend_doubleround_body 26, sp, r9, r10, r7, r8
178	sha256_extend_doubleround_body 28, sp, r4, r5, r9, r10
179	sha256_extend_doubleround_body 30, sp, r6, r7, r4, r5
180	sha256_extend_doubleround_body 32, sp, r8, r9, r6, r7
181	sha256_extend_doubleround_body 34, sp, r10, r4, r8, r9
182	sha256_extend_doubleround_body 36, sp, r5, r6, r10, r4
183	sha256_extend_doubleround_body 38, sp, r7, r8, r5, r6
184	sha256_extend_doubleround_body 40, sp, r9, r10, r7, r8
185	sha256_extend_doubleround_body 42, sp, r4, r5, r9, r10
186	sha256_extend_doubleround_body 44, sp, r6, r7, r4, r5
187	sha256_extend_doubleround_foot 46, sp, r8, r9, r6, r7
188
189	ldmia	r0, {r4-r11}
190	sha256_main_quadround  0, sha256_transform_k, sp
191	sha256_main_quadround  4, sha256_transform_k, sp
192	sha256_main_quadround  8, sha256_transform_k, sp
193	sha256_main_quadround 12, sha256_transform_k, sp
194	sha256_main_quadround 16, sha256_transform_k, sp
195	sha256_main_quadround 20, sha256_transform_k, sp
196	sha256_main_quadround 24, sha256_transform_k, sp
197	sha256_main_quadround 28, sha256_transform_k, sp
198	b	sha256_transform_k_over
199sha256_transform_k:
200	sha256_k
201sha256_transform_k_over:
202	sha256_main_quadround 32, sha256_transform_k, sp
203	sha256_main_quadround 36, sha256_transform_k, sp
204	sha256_main_quadround 40, sha256_transform_k, sp
205	sha256_main_quadround 44, sha256_transform_k, sp
206	sha256_main_quadround 48, sha256_transform_k, sp
207	sha256_main_quadround 52, sha256_transform_k, sp
208	sha256_main_quadround 56, sha256_transform_k, sp
209	sha256_main_quadround 60, sha256_transform_k, sp
210
211	ldmia	r0, {r1, r2, r3, r12}
212	add	r4, r4, r1
213	add	r5, r5, r2
214	add	r6, r6, r3
215	add	r7, r7, r12
216	stmia	r0!, {r4-r7}
217	ldmia	r0, {r1, r2, r3, r12}
218	add	r8, r8, r1
219	add	r9, r9, r2
220	add	r10, r10, r3
221	add	r11, r11, r12
222	stmia	r0, {r8-r11}
223
224	add	sp, sp, #64*4
225#ifdef __thumb__
226	ldmfd	sp!, {r4-r11, lr}
227	bx	lr
228#else
229	ldmfd	sp!, {r4-r11, pc}
230#endif
231
232
233	.text
234	.code 32
235	.align 2
236	.globl sha256d_ms
237	.globl _sha256d_ms
238#ifdef __ELF__
239	.type sha256d_ms, %function
240#endif
241sha256d_ms:
242_sha256d_ms:
243	stmfd	sp!, {r4-r11, lr}
244	sub	sp, sp, #64*4
245
246	cmp	r0, r0
247
248	ldr	lr, [r1, #3*4]
249	ldr	r6, [r1, #18*4]
250	ldr	r7, [r1, #19*4]
251
252	mov	r12, lr, ror #7
253	str	r6, [sp, #18*4]
254	eor	r12, r12, lr, ror #18
255	str	r7, [sp, #19*4]
256	eor	r12, r12, lr, lsr #3
257	ldr	r8, [r1, #20*4]
258	add	r6, r6, r12
259	ldr	r10, [r1, #22*4]
260	add	r7, r7, lr
261	str	r6, [r1, #18*4]
262
263	mov	r12, r6, ror #17
264	str	r7, [r1, #19*4]
265	eor	r12, r12, r6, ror #19
266	str	r8, [sp, #20*4]
267	eor	r12, r12, r6, lsr #10
268	ldr	r4, [r1, #23*4]
269	add	r8, r8, r12
270	ldr	r5, [r1, #24*4]
271
272	mov	r9, r7, ror #17
273	str	r8, [r1, #20*4]
274	eor	r9, r9, r7, ror #19
275	str	r10, [sp, #21*4]
276	eor	r9, r9, r7, lsr #10
277	str	r4, [sp, #22*4]
278
279	mov	r12, r8, ror #17
280	str	r9, [r1, #21*4]
281	eor	r12, r12, r8, ror #19
282	str	r5, [sp, #23*4]
283	eor	r12, r12, r8, lsr #10
284	mov	lr, r9, ror #17
285	add	r10, r10, r12
286	ldr	r11, [r1, #30*4]
287
288	eor	lr, lr, r9, ror #19
289	str	r10, [r1, #22*4]
290	eor	lr, lr, r9, lsr #10
291	str	r11, [sp, #24*4]
292	add	r4, r4, lr
293
294	mov	r12, r10, ror #17
295	str	r4, [r1, #23*4]
296	eor	r12, r12, r10, ror #19
297	mov	lr, r4, ror #17
298	eor	r12, r12, r10, lsr #10
299	eor	lr, lr, r4, ror #19
300	add	r5, r5, r12
301	eor	lr, lr, r4, lsr #10
302	str	r5, [r1, #24*4]
303	add	r6, r6, lr
304
305	mov	r12, r5, ror #17
306	str	r6, [r1, #25*4]
307	eor	r12, r12, r5, ror #19
308	mov	lr, r6, ror #17
309	eor	r12, r12, r5, lsr #10
310	eor	lr, lr, r6, ror #19
311	add	r7, r7, r12
312	eor	lr, lr, r6, lsr #10
313	str	r7, [r1, #26*4]
314	add	r8, r8, lr
315
316	mov	r12, r7, ror #17
317	str	r8, [r1, #27*4]
318	eor	r12, r12, r7, ror #19
319	mov	lr, r8, ror #17
320	eor	r12, r12, r7, lsr #10
321	eor	lr, lr, r8, ror #19
322	add	r9, r9, r12
323	eor	lr, lr, r8, lsr #10
324	str	r9, [r1, #28*4]
325	add	r10, r10, lr
326
327	ldr	lr, [r1, #31*4]
328	mov	r12, r9, ror #17
329	str	r10, [r1, #29*4]
330	eor	r12, r12, r9, ror #19
331	str	lr, [sp, #25*4]
332	eor	r12, r12, r9, lsr #10
333	add	r11, r11, r12
334	add	r5, r5, lr
335	mov	r12, r10, ror #17
336	add	r4, r4, r11
337
338	ldr	r11, [r1, #16*4]
339	eor	r12, r12, r10, ror #19
340	str	r4, [r1, #30*4]
341	eor	r12, r12, r10, lsr #10
342	add	r5, r5, r12
343	ldr	lr, [r1, #17*4]
344
345sha256d_ms_extend_loop2:
346	sha256_extend_doubleround_body 16, r1, r6, r7, r4, r5
347	sha256_extend_doubleround_body 18, r1, r8, r9, r6, r7
348	sha256_extend_doubleround_body 20, r1, r10, r4, r8, r9
349	sha256_extend_doubleround_body 22, r1, r5, r6, r10, r4
350	sha256_extend_doubleround_body 24, r1, r7, r8, r5, r6
351	sha256_extend_doubleround_body 26, r1, r9, r10, r7, r8
352	sha256_extend_doubleround_body 28, r1, r4, r5, r9, r10
353	sha256_extend_doubleround_body 30, r1, r6, r7, r4, r5
354	sha256_extend_doubleround_body 32, r1, r8, r9, r6, r7
355	sha256_extend_doubleround_body 34, r1, r10, r4, r8, r9
356	sha256_extend_doubleround_body 36, r1, r5, r6, r10, r4
357	sha256_extend_doubleround_body 38, r1, r7, r8, r5, r6
358	sha256_extend_doubleround_body 40, r1, r9, r10, r7, r8
359	sha256_extend_doubleround_body 42, r1, r4, r5, r9, r10
360	bne	sha256d_ms_extend_coda2
361	sha256_extend_doubleround_body 44, r1, r6, r7, r4, r5
362	sha256_extend_doubleround_foot 46, r1, r8, r9, r6, r7
363
364	ldr	r4,  [r3, #0*4]
365	ldr	r9,  [r3, #1*4]
366	ldr	r10, [r3, #2*4]
367	ldr	r11, [r3, #3*4]
368	ldr	r8,  [r3, #4*4]
369	ldr	r5,  [r3, #5*4]
370	ldr	r6,  [r3, #6*4]
371	ldr	r7,  [r3, #7*4]
372	b	sha256d_ms_main_loop1
373
374sha256d_ms_main_loop2:
375	sha256_main_round  0, sha256d_ms_k, r1, r4, r5, r6, r7, r8, r9, r10, r11
376	sha256_main_round  1, sha256d_ms_k, r1, r7, r4, r5, r6, r11, r8, r9, r10
377	sha256_main_round  2, sha256d_ms_k, r1, r6, r7, r4, r5, r10, r11, r8, r9
378sha256d_ms_main_loop1:
379	sha256_main_round  3, sha256d_ms_k, r1, r5, r6, r7, r4, r9, r10, r11, r8
380	sha256_main_quadround  4, sha256d_ms_k, r1
381	sha256_main_quadround  8, sha256d_ms_k, r1
382	sha256_main_quadround 12, sha256d_ms_k, r1
383	sha256_main_quadround 16, sha256d_ms_k, r1
384	sha256_main_quadround 20, sha256d_ms_k, r1
385	sha256_main_quadround 24, sha256d_ms_k, r1
386	sha256_main_quadround 28, sha256d_ms_k, r1
387	b	sha256d_ms_k_over
388sha256d_ms_k:
389	sha256_k
390sha256d_ms_k_over:
391	sha256_main_quadround 32, sha256d_ms_k, r1
392	sha256_main_quadround 36, sha256d_ms_k, r1
393	sha256_main_quadround 40, sha256d_ms_k, r1
394	sha256_main_quadround 44, sha256d_ms_k, r1
395	sha256_main_quadround 48, sha256d_ms_k, r1
396	sha256_main_quadround 52, sha256d_ms_k, r1
397	sha256_main_round 56, sha256d_ms_k, r1, r4, r5, r6, r7, r8, r9, r10, r11
398	bne	sha256d_ms_finish
399	sha256_main_round 57, sha256d_ms_k, r1, r7, r4, r5, r6, r11, r8, r9, r10
400	sha256_main_round 58, sha256d_ms_k, r1, r6, r7, r4, r5, r10, r11, r8, r9
401	sha256_main_round 59, sha256d_ms_k, r1, r5, r6, r7, r4, r9, r10, r11, r8
402	sha256_main_quadround 60, sha256d_ms_k, r1
403
404	ldmia	r2!, {r3, r12, lr}
405	add	r4, r4, r3
406	add	r5, r5, r12
407	add	r6, r6, lr
408	stmia	sp, {r4-r6}
409	ldmia	r2, {r3, r4, r5, r6, r12}
410	add	lr, sp, #3*4
411	add	r7, r7, r3
412	add	r8, r8, r4
413	add	r9, r9, r5
414	add	r10, r10, r6
415	add	r11, r11, r12
416	add	r12, sp, #18*4
417	stmia	lr!, {r7-r11}
418
419	ldmia	r12, {r4-r11}
420	str	r4,  [r1, #18*4]
421	str	r5,  [r1, #19*4]
422	str	r6,  [r1, #20*4]
423	str	r7,  [r1, #22*4]
424	str	r8,  [r1, #23*4]
425	str	r9,  [r1, #24*4]
426	str	r10, [r1, #30*4]
427	str	r11, [r1, #31*4]
428
429	mov	r3,  #0x80000000
430	mov	r4,  #0
431	mov	r5,  #0
432	mov	r6,  #0
433	mov	r7,  #0
434	mov	r8,  #0
435	mov	r9,  #0
436	mov	r10, #0x00000100
437	stmia	lr, {r3-r10}
438
439	ldr	lr, [sp, #1*4]
440	movs	r1, sp
441	ldr	r4, [sp, #0*4]
442
443	ldr	r11, [sp, #2*4]
444	mov	r12, lr, ror #7
445	eor	r12, r12, lr, ror #18
446	add	r5, lr, #0x00a00000
447	eor	r12, r12, lr, lsr #3
448	mov	lr, r11, ror #7
449	add	r4, r4, r12
450	eor	lr, lr, r11, ror #18
451	str	r4, [sp, #16*4]
452	eor	lr, lr, r11, lsr #3
453	mov	r12, r4, ror #17
454	add	r5, r5, lr
455	ldr	lr, [sp, #3*4]
456
457	str	r5, [sp, #17*4]
458	eor	r12, r12, r4, ror #19
459	mov	r6, lr, ror #7
460	eor	r12, r12, r4, lsr #10
461	eor	r6, r6, lr, ror #18
462	add	r11, r11, r12
463	eor	r6, r6, lr, lsr #3
464	mov	r12, r5, ror #17
465	add	r6, r6, r11
466	ldr	r11, [sp, #4*4]
467
468	str	r6, [sp, #18*4]
469	eor	r12, r12, r5, ror #19
470	mov	r7, r11, ror #7
471	eor	r12, r12, r5, lsr #10
472	eor	r7, r7, r11, ror #18
473	add	lr, lr, r12
474	eor	r7, r7, r11, lsr #3
475	mov	r12, r6, ror #17
476	add	r7, r7, lr
477	ldr	lr, [sp, #5*4]
478
479	str	r7, [sp, #19*4]
480	eor	r12, r12, r6, ror #19
481	mov	r8, lr, ror #7
482	eor	r12, r12, r6, lsr #10
483	eor	r8, r8, lr, ror #18
484	add	r11, r11, r12
485	eor	r8, r8, lr, lsr #3
486	mov	r12, r7, ror #17
487	add	r8, r8, r11
488	ldr	r11, [sp, #6*4]
489
490	str	r8, [sp, #20*4]
491	eor	r12, r12, r7, ror #19
492	mov	r9, r11, ror #7
493	eor	r12, r12, r7, lsr #10
494	eor	r9, r9, r11, ror #18
495	add	lr, lr, r12
496	eor	r9, r9, r11, lsr #3
497	mov	r12, r8, ror #17
498	add	r9, r9, lr
499	ldr	lr, [sp, #7*4]
500
501	str	r9, [sp, #21*4]
502	eor	r12, r12, r8, ror #19
503	mov	r10, lr, ror #7
504	eor	r12, r12, r8, lsr #10
505	eor	r10, r10, lr, ror #18
506	add	r11, r11, r12
507	eor	r10, r10, lr, lsr #3
508	mov	r12, r9, ror #17
509	add	r11, r11, #0x00000100
510	add	lr, lr, r4
511	add	r10, r10, r11
512
513	eor	r12, r12, r9, ror #19
514	str	r10, [sp, #22*4]
515	add	lr, lr, #0x11000000
516	eor	r12, r12, r9, lsr #10
517	add	lr, lr, r12
518	mov	r12, r10, ror #17
519	add	r4, lr, #0x00002000
520	eor	r12, r12, r10, ror #19
521	str	r4, [sp, #23*4]
522	add	r5, r5, #0x80000000
523	eor	r12, r12, r10, lsr #10
524	add	r5, r5, r12
525
526	mov	r12, r4, ror #17
527	str	r5, [sp, #24*4]
528	eor	r12, r12, r4, ror #19
529	mov	r11, r5, ror #17
530	eor	r12, r12, r4, lsr #10
531	eor	r11, r11, r5, ror #19
532	add	r6, r6, r12
533	eor	r11, r11, r5, lsr #10
534	str	r6, [sp, #25*4]
535	add	r7, r7, r11
536
537	mov	r12, r6, ror #17
538	str	r7, [sp, #26*4]
539	eor	r12, r12, r6, ror #19
540	mov	r11, r7, ror #17
541	eor	r12, r12, r6, lsr #10
542	eor	r11, r11, r7, ror #19
543	add	r8, r8, r12
544	eor	r11, r11, r7, lsr #10
545	str	r8, [sp, #27*4]
546	add	r9, r9, r11
547
548	mov	lr, r8, ror #17
549	mov	r12, r9, ror #17
550	str	r9, [sp, #28*4]
551	add	r4, r4, #0x00400000
552	eor	lr, lr, r8, ror #19
553	eor	r12, r12, r9, ror #19
554	eor	lr, lr, r8, lsr #10
555	eor	r12, r12, r9, lsr #10
556	add	r4, r4, #0x00000022
557	add	r10, r10, lr
558	add	r4, r4, r12
559	ldr	r11, [sp, #16*4]
560
561	add	r5, r5, #0x00000100
562	str	r4, [sp, #30*4]
563	mov	lr, r11, ror #7
564	str	r10, [sp, #29*4]
565	mov	r12, r10, ror #17
566	eor	lr, lr, r11, ror #18
567	eor	r12, r12, r10, ror #19
568	eor	lr, lr, r11, lsr #3
569	eor	r12, r12, r10, lsr #10
570	add	r5, r5, lr
571	ldr	lr, [r1, #17*4]
572	add	r5, r5, r12
573
574	b	sha256d_ms_extend_loop2
575
576sha256d_ms_extend_coda2:
577	str	r5, [r1, #(44+15)*4]
578	mov	r12, r4, ror #17
579	add	r11, r11, r6
580	mov	r6, lr, ror #7
581	eor	r12, r12, r4, ror #19
582	eor	r6, r6, lr, ror #18
583	eor	r12, r12, r4, lsr #10
584	eor	r6, r6, lr, lsr #3
585	add	r12, r12, r11
586	add	r6, r6, r12
587	str	r6, [r1, #(44+16)*4]
588
589	adr	r2, sha256d_ms_h
590	ldmia	r2, {r4-r11}
591	b	sha256d_ms_main_loop2
592
593sha256d_ms_h:
594	.long 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a
595	.long 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
596
597.macro sha256_main_round_red i, ka, rw, rd, re, rf, rg, rh
598	ldr	r12, [\rw, #(\i)*4]
599	and	r3, \rf, \re
600	bic	lr, \rg, \re
601	add	\rh, \rh, \rd
602	orr	lr, lr, r3
603	ldr	r3, \ka + (\i)*4
604	add	\rh, \rh, lr
605	eor	lr, \re, \re, ror #5
606	add	\rh, \rh, r12
607	eor	lr, lr, \re, ror #19
608	add	\rh, \rh, r3
609	add	\rh, \rh, lr, ror #6
610.endm
611
612sha256d_ms_finish:
613	sha256_main_round_red 57, sha256d_ms_k, r1, r6, r11, r8, r9, r10
614	sha256_main_round_red 58, sha256d_ms_k, r1, r5, r10, r11, r8, r9
615	sha256_main_round_red 59, sha256d_ms_k, r1, r4, r9, r10, r11, r8
616	ldr	r5, [r2, #7*4]
617	sha256_main_round_red 60, sha256d_ms_k, r1, r7, r8, r9, r10, r11
618
619	add	r11, r11, r5
620	str	r11, [r0, #7*4]
621
622	add	sp, sp, #64*4
623#ifdef __thumb__
624	ldmfd	sp!, {r4-r11, lr}
625	bx	lr
626#else
627	ldmfd	sp!, {r4-r11, pc}
628#endif
629
630
631#ifdef __ARM_NEON__
632
633	.text
634	.code 32
635	.align 2
636	.globl sha256_init_4way
637	.globl _sha256_init_4way
638#ifdef __ELF__
639	.type sha256_init_4way, %function
640#endif
641sha256_init_4way:
642_sha256_init_4way:
643	adr	r12, sha256_4h
644	vldmia	r12, {q8-q15}
645	vstmia	r0, {q8-q15}
646	bx	lr
647	.align 4
648sha256_4h:
649	.long 0x6a09e667, 0x6a09e667, 0x6a09e667, 0x6a09e667
650	.long 0xbb67ae85, 0xbb67ae85, 0xbb67ae85, 0xbb67ae85
651	.long 0x3c6ef372, 0x3c6ef372, 0x3c6ef372, 0x3c6ef372
652	.long 0xa54ff53a, 0xa54ff53a, 0xa54ff53a, 0xa54ff53a
653	.long 0x510e527f, 0x510e527f, 0x510e527f, 0x510e527f
654	.long 0x9b05688c, 0x9b05688c, 0x9b05688c, 0x9b05688c
655	.long 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab
656	.long 0x5be0cd19, 0x5be0cd19, 0x5be0cd19, 0x5be0cd19
657
658.macro sha256_4k
659	.long 0x428a2f98, 0x428a2f98, 0x428a2f98, 0x428a2f98
660	.long 0x71374491, 0x71374491, 0x71374491, 0x71374491
661	.long 0xb5c0fbcf, 0xb5c0fbcf, 0xb5c0fbcf, 0xb5c0fbcf
662	.long 0xe9b5dba5, 0xe9b5dba5, 0xe9b5dba5, 0xe9b5dba5
663	.long 0x3956c25b, 0x3956c25b, 0x3956c25b, 0x3956c25b
664	.long 0x59f111f1, 0x59f111f1, 0x59f111f1, 0x59f111f1
665	.long 0x923f82a4, 0x923f82a4, 0x923f82a4, 0x923f82a4
666	.long 0xab1c5ed5, 0xab1c5ed5, 0xab1c5ed5, 0xab1c5ed5
667	.long 0xd807aa98, 0xd807aa98, 0xd807aa98, 0xd807aa98
668	.long 0x12835b01, 0x12835b01, 0x12835b01, 0x12835b01
669	.long 0x243185be, 0x243185be, 0x243185be, 0x243185be
670	.long 0x550c7dc3, 0x550c7dc3, 0x550c7dc3, 0x550c7dc3
671	.long 0x72be5d74, 0x72be5d74, 0x72be5d74, 0x72be5d74
672	.long 0x80deb1fe, 0x80deb1fe, 0x80deb1fe, 0x80deb1fe
673	.long 0x9bdc06a7, 0x9bdc06a7, 0x9bdc06a7, 0x9bdc06a7
674	.long 0xc19bf174, 0xc19bf174, 0xc19bf174, 0xc19bf174
675	.long 0xe49b69c1, 0xe49b69c1, 0xe49b69c1, 0xe49b69c1
676	.long 0xefbe4786, 0xefbe4786, 0xefbe4786, 0xefbe4786
677	.long 0x0fc19dc6, 0x0fc19dc6, 0x0fc19dc6, 0x0fc19dc6
678	.long 0x240ca1cc, 0x240ca1cc, 0x240ca1cc, 0x240ca1cc
679	.long 0x2de92c6f, 0x2de92c6f, 0x2de92c6f, 0x2de92c6f
680	.long 0x4a7484aa, 0x4a7484aa, 0x4a7484aa, 0x4a7484aa
681	.long 0x5cb0a9dc, 0x5cb0a9dc, 0x5cb0a9dc, 0x5cb0a9dc
682	.long 0x76f988da, 0x76f988da, 0x76f988da, 0x76f988da
683	.long 0x983e5152, 0x983e5152, 0x983e5152, 0x983e5152
684	.long 0xa831c66d, 0xa831c66d, 0xa831c66d, 0xa831c66d
685	.long 0xb00327c8, 0xb00327c8, 0xb00327c8, 0xb00327c8
686	.long 0xbf597fc7, 0xbf597fc7, 0xbf597fc7, 0xbf597fc7
687	.long 0xc6e00bf3, 0xc6e00bf3, 0xc6e00bf3, 0xc6e00bf3
688	.long 0xd5a79147, 0xd5a79147, 0xd5a79147, 0xd5a79147
689	.long 0x06ca6351, 0x06ca6351, 0x06ca6351, 0x06ca6351
690	.long 0x14292967, 0x14292967, 0x14292967, 0x14292967
691	.long 0x27b70a85, 0x27b70a85, 0x27b70a85, 0x27b70a85
692	.long 0x2e1b2138, 0x2e1b2138, 0x2e1b2138, 0x2e1b2138
693	.long 0x4d2c6dfc, 0x4d2c6dfc, 0x4d2c6dfc, 0x4d2c6dfc
694	.long 0x53380d13, 0x53380d13, 0x53380d13, 0x53380d13
695	.long 0x650a7354, 0x650a7354, 0x650a7354, 0x650a7354
696	.long 0x766a0abb, 0x766a0abb, 0x766a0abb, 0x766a0abb
697	.long 0x81c2c92e, 0x81c2c92e, 0x81c2c92e, 0x81c2c92e
698	.long 0x92722c85, 0x92722c85, 0x92722c85, 0x92722c85
699	.long 0xa2bfe8a1, 0xa2bfe8a1, 0xa2bfe8a1, 0xa2bfe8a1
700	.long 0xa81a664b, 0xa81a664b, 0xa81a664b, 0xa81a664b
701	.long 0xc24b8b70, 0xc24b8b70, 0xc24b8b70, 0xc24b8b70
702	.long 0xc76c51a3, 0xc76c51a3, 0xc76c51a3, 0xc76c51a3
703	.long 0xd192e819, 0xd192e819, 0xd192e819, 0xd192e819
704	.long 0xd6990624, 0xd6990624, 0xd6990624, 0xd6990624
705	.long 0xf40e3585, 0xf40e3585, 0xf40e3585, 0xf40e3585
706	.long 0x106aa070, 0x106aa070, 0x106aa070, 0x106aa070
707	.long 0x19a4c116, 0x19a4c116, 0x19a4c116, 0x19a4c116
708	.long 0x1e376c08, 0x1e376c08, 0x1e376c08, 0x1e376c08
709	.long 0x2748774c, 0x2748774c, 0x2748774c, 0x2748774c
710	.long 0x34b0bcb5, 0x34b0bcb5, 0x34b0bcb5, 0x34b0bcb5
711	.long 0x391c0cb3, 0x391c0cb3, 0x391c0cb3, 0x391c0cb3
712	.long 0x4ed8aa4a, 0x4ed8aa4a, 0x4ed8aa4a, 0x4ed8aa4a
713	.long 0x5b9cca4f, 0x5b9cca4f, 0x5b9cca4f, 0x5b9cca4f
714	.long 0x682e6ff3, 0x682e6ff3, 0x682e6ff3, 0x682e6ff3
715	.long 0x748f82ee, 0x748f82ee, 0x748f82ee, 0x748f82ee
716	.long 0x78a5636f, 0x78a5636f, 0x78a5636f, 0x78a5636f
717	.long 0x84c87814, 0x84c87814, 0x84c87814, 0x84c87814
718	.long 0x8cc70208, 0x8cc70208, 0x8cc70208, 0x8cc70208
719	.long 0x90befffa, 0x90befffa, 0x90befffa, 0x90befffa
720	.long 0xa4506ceb, 0xa4506ceb, 0xa4506ceb, 0xa4506ceb
721	.long 0xbef9a3f7, 0xbef9a3f7, 0xbef9a3f7, 0xbef9a3f7
722	.long 0xc67178f2, 0xc67178f2, 0xc67178f2, 0xc67178f2
723.endm
724
725.macro sha256_4way_extend_doubleround_core i, rr, rw, ra, rb, ry, rz
726	vadd.u32	q5, q5, \ra
727	veor.u32	q4, q4, q0
728	vshr.u32	q0, \ry, #19
729	vshl.u32	q1, \ry, #32-19
730	veor.u32	q4, q4, q0
731	vshr.u32	\ra, q6, #7
732	vshl.u32	q0, q6, #32-7
733	veor.u32	q4, q4, q1
734	veor.u32	\ra, \ra, q0
735	vshr.u32	q1, \ry, #10
736	vshr.u32	q0, q6, #18
737	veor.u32	q4, q4, q1
738	veor.u32	\ra, \ra, q0
739	vshl.u32	q1, q6, #32-18
740	vshr.u32	q0, q6, #3
741	veor.u32	\ra, \ra, q1
742	vadd.u32	q4, q4, q5
743	veor.u32	\ra, \ra, q0
744	vld1.u32	{q5}, [\rr]!
745	vadd.u32	\ra, \ra, q4
746
747	vshr.u32	q4, \rz, #17
748	vshl.u32	q0, \rz, #32-17
749	vadd.u32	q6, q6, \rb
750	vst1.u32	{\ra}, [\rw]!
751	veor.u32	q4, q4, q0
752	vshr.u32	q0, \rz, #19
753	vshl.u32	q1, \rz, #32-19
754	veor.u32	q4, q4, q0
755	vshr.u32	\rb, q5, #7
756	veor.u32	q4, q4, q1
757	vshl.u32	q0, q5, #32-7
758	vshr.u32	q1, \rz, #10
759	veor.u32	\rb, \rb, q0
760	vshr.u32	q0, q5, #18
761	veor.u32	q4, q4, q1
762	veor.u32	\rb, \rb, q0
763	vshl.u32	q1, q5, #32-18
764	vshr.u32	q0, q5, #3
765	veor.u32	\rb, \rb, q1
766	vadd.u32	q1, q6, q4
767	veor.u32	\rb, \rb, q0
768.endm
769
770.macro sha256_4way_extend_doubleround_head i, rr, rw, ra, rb, ry, rz
771	vld1.u32	{q6}, [\rr]!
772	vshr.u32	q4, \ry, #17
773	vshl.u32	q0, \ry, #32-17
774	sha256_4way_extend_doubleround_core \i, \rr, \rw, \ra, \rb, \ry, \rz
775	vld1.u32	{q6}, [\rr]!
776	vadd.u32	\rb, \rb, q1
777.endm
778
779.macro sha256_4way_extend_doubleround_body i, rr, rw, ra, rb, ry, rz
780	vshr.u32	q4, \ry, #17
781	vshl.u32	q0, \ry, #32-17
782	vst1.u32	{\rz}, [\rw]!
783	sha256_4way_extend_doubleround_core \i, \rr, \rw, \ra, \rb, \ry, \rz
784	vld1.u32	{q6}, [\rr]!
785	vadd.u32	\rb, \rb, q1
786.endm
787
788.macro sha256_4way_extend_doubleround_foot i, rr, rw, ra, rb, ry, rz
789	vshr.u32	q4, \ry, #17
790	vshl.u32	q0, \ry, #32-17
791	vst1.u32	{\rz}, [\rw]!
792	sha256_4way_extend_doubleround_core \i, \rr, \rw, \ra, \rb, \ry, \rz
793	vadd.u32	\rb, \rb, q1
794	vst1.u32	{\rb}, [\rw]!
795.endm
796
797.macro sha256_4way_main_round i, rk, rw, ra, rb, rc, rd, re, rf, rg, rh
798	vld1.u32	{q8}, [\rw]!
799	vand.u32	q9, \rf, \re
800	vbic.u32	q10, \rg, \re
801	vshr.u32	q11, \re, #5
802	vorr.u32	q10, q10, q9
803	vld1.u32	{q9}, [\rk]!
804	vadd.u32	\rh, \rh, q10
805	vshl.u32	q12, \re, #32-5
806	veor.u32	q10, \re, q11
807	vshr.u32	q11, \re, #19
808	veor.u32	q10, q10, q12
809	vshl.u32	q12, \re, #32-19
810	veor.u32	q10, q10, q11
811	vadd.u32	\rh, \rh, q8
812	veor.u32	q10, q10, q12
813	vadd.u32	\rh, \rh, q9
814	veor.u32	q9, \ra, \rb
815	vshr.u32	q11, q10, #6
816	vshl.u32	q13, q10, #32-6
817	vadd.u32	\rh, \rh, q11
818
819	vshr.u32	q11, \ra, #11
820	vshl.u32	q12, \ra, #32-11
821	veor.u32	q8, \ra, q11
822	vand.u32	q10, \ra, \rb
823	veor.u32	q8, q8, q12
824	vshr.u32	q11, \ra, #20
825	vshl.u32	q12, \ra, #32-20
826	veor.u32	q8, q8, q11
827	vand.u32	q9, q9, \rc
828	veor.u32	q8, q8, q12
829	vadd.u32	\rh, \rh, q13
830	veor.u32	q10, q10, q9
831	vshr.u32	q11, q8, #2
832	vshl.u32	q12, q8, #32-2
833	vadd.u32	q9, \rh, q10
834	vadd.u32	q12, q12, q11
835	vadd.u32	\rh, \rh, \rd
836	vadd.u32	\rd, q9, q12
837.endm
838
839.macro sha256_4way_main_quadround i, rk, rw
840	sha256_4way_main_round \i+0, \rk, \rw, q0, q1, q2, q3, q4, q5, q6, q7
841	sha256_4way_main_round \i+1, \rk, \rw, q3, q0, q1, q2, q7, q4, q5, q6
842	sha256_4way_main_round \i+2, \rk, \rw, q2, q3, q0, q1, q6, q7, q4, q5
843	sha256_4way_main_round \i+3, \rk, \rw, q1, q2, q3, q0, q5, q6, q7, q4
844.endm
845
846
847	.text
848	.code 32
849	.align 2
850	.globl sha256_transform_4way
851	.globl _sha256_transform_4way
852#ifdef __ELF__
853	.type sha256_transform_4way, %function
854#endif
855sha256_transform_4way:
856_sha256_transform_4way:
857	stmfd	sp!, {r4, lr}
858	vpush	{q4-q7}
859	mov	r12, sp
860	sub	sp, sp, #64*16
861	bic	sp, sp, #63
862	cmp	r2, #0
863	bne	sha256_transform_4way_swap
864
865	vldmia	r1!, {q0-q7}
866	vstmia	sp, {q0-q7}
867	add	r3, sp, #8*16
868	vldmia	r1, {q8-q15}
869	vstmia	r3, {q8-q15}
870	b	sha256_transform_4way_extend
871
872sha256_transform_4way_swap:
873	vldmia	r1!, {q0-q7}
874	vrev32.8	q0, q0
875	vrev32.8	q1, q1
876	vrev32.8	q2, q2
877	vrev32.8	q3, q3
878	vldmia	r1, {q8-q15}
879	vrev32.8	q4, q4
880	vrev32.8	q5, q5
881	vrev32.8	q6, q6
882	vrev32.8	q7, q7
883	vstmia	sp, {q0-q7}
884	vrev32.8	q8, q8
885	vrev32.8	q9, q9
886	vrev32.8	q10, q10
887	vrev32.8	q11, q11
888	vrev32.8	q12, q12
889	vrev32.8	q13, q13
890	vrev32.8	q14, q14
891	vrev32.8	q15, q15
892	add	r3, sp, #8*16
893	vstmia	r3, {q8-q15}
894
895sha256_transform_4way_extend:
896	add	r1, sp, #1*16
897	add	r2, sp, #16*16
898	vmov.u32	q5, q0
899	sha256_4way_extend_doubleround_head  0, r1, r2,  q9, q10, q14, q15
900	sha256_4way_extend_doubleround_body  2, r1, r2, q11, q12,  q9, q10
901	sha256_4way_extend_doubleround_body  4, r1, r2, q13, q14, q11, q12
902	sha256_4way_extend_doubleround_body  6, r1, r2, q15,  q9, q13, q14
903	sha256_4way_extend_doubleround_body  8, r1, r2, q10, q11, q15,  q9
904	sha256_4way_extend_doubleround_body 10, r1, r2, q12, q13, q10, q11
905	sha256_4way_extend_doubleround_body 12, r1, r2, q14, q15, q12, q13
906	sha256_4way_extend_doubleround_body 14, r1, r2,  q9, q10, q14, q15
907	sha256_4way_extend_doubleround_body 16, r1, r2, q11, q12,  q9, q10
908	sha256_4way_extend_doubleround_body 18, r1, r2, q13, q14, q11, q12
909	sha256_4way_extend_doubleround_body 20, r1, r2, q15,  q9, q13, q14
910	sha256_4way_extend_doubleround_body 22, r1, r2, q10, q11, q15,  q9
911	sha256_4way_extend_doubleround_body 24, r1, r2, q12, q13, q10, q11
912	sha256_4way_extend_doubleround_body 26, r1, r2, q14, q15, q12, q13
913	sha256_4way_extend_doubleround_body 28, r1, r2,  q9, q10, q14, q15
914	sha256_4way_extend_doubleround_body 30, r1, r2, q11, q12,  q9, q10
915	sha256_4way_extend_doubleround_body 32, r1, r2, q13, q14, q11, q12
916	sha256_4way_extend_doubleround_body 34, r1, r2, q15,  q9, q13, q14
917	sha256_4way_extend_doubleround_body 36, r1, r2, q10, q11, q15,  q9
918	sha256_4way_extend_doubleround_body 38, r1, r2, q12, q13, q10, q11
919	sha256_4way_extend_doubleround_body 40, r1, r2, q14, q15, q12, q13
920	sha256_4way_extend_doubleround_body 42, r1, r2,  q9, q10, q14, q15
921	sha256_4way_extend_doubleround_body 44, r1, r2, q11, q12,  q9, q10
922	sha256_4way_extend_doubleround_foot 46, r1, r2, q13, q14, q11, q12
923
924	vldmia	r0, {q0-q7}
925	adr	r4, sha256_transform_4way_4k
926	b	sha256_transform_4way_4k_over
927	.align 4
928sha256_transform_4way_4k:
929	sha256_4k
930sha256_transform_4way_4k_over:
931	sha256_4way_main_quadround  0, r4, sp
932	sha256_4way_main_quadround  4, r4, sp
933	sha256_4way_main_quadround  8, r4, sp
934	sha256_4way_main_quadround 12, r4, sp
935	sha256_4way_main_quadround 16, r4, sp
936	sha256_4way_main_quadround 20, r4, sp
937	sha256_4way_main_quadround 24, r4, sp
938	sha256_4way_main_quadround 28, r4, sp
939	sha256_4way_main_quadround 32, r4, sp
940	sha256_4way_main_quadround 36, r4, sp
941	sha256_4way_main_quadround 40, r4, sp
942	sha256_4way_main_quadround 44, r4, sp
943	sha256_4way_main_quadround 48, r4, sp
944	sha256_4way_main_quadround 52, r4, sp
945	sha256_4way_main_quadround 56, r4, sp
946	sha256_4way_main_quadround 60, r4, sp
947
948	vldmia	r0, {q8-q15}
949	vadd.u32	q0, q0, q8
950	vadd.u32	q1, q1, q9
951	vadd.u32	q2, q2, q10
952	vadd.u32	q3, q3, q11
953	vadd.u32	q4, q4, q12
954	vadd.u32	q5, q5, q13
955	vadd.u32	q6, q6, q14
956	vadd.u32	q7, q7, q15
957	vstmia	r0, {q0-q7}
958
959	mov	sp, r12
960	vpop	{q4-q7}
961	ldmfd	sp!, {r4, pc}
962
963
964	.text
965	.code 32
966	.align 2
967	.globl sha256d_ms_4way
968	.globl _sha256d_ms_4way
969#ifdef __ELF__
970	.type sha256d_ms_4way, %function
971#endif
972sha256d_ms_4way:
973_sha256d_ms_4way:
974	stmfd	sp!, {r4, lr}
975	vpush	{q4-q7}
976	mov	r12, sp
977	sub	sp, sp, #64*16
978	bic	sp, sp, #63
979
980	add	r4, r1, #3*16
981	vld1.u32	{q6}, [r4]!
982	add	r1, r1, #18*16
983	vldmia	r1, {q11-q13}
984	cmp	r0, r0
985
986	vshr.u32	q10, q6, #7
987	vshl.u32	q0, q6, #32-7
988	vshr.u32	q1, q6, #18
989	veor.u32	q10, q10, q0
990	vshl.u32	q0, q6, #32-18
991	veor.u32	q10, q10, q1
992	vshr.u32	q1, q6, #3
993	veor.u32	q10, q10, q0
994	vstmia	sp!, {q11-q13}
995	veor.u32	q4, q10, q1
996	vadd.u32	q12, q12, q6
997	vadd.u32	q11, q11, q4
998
999	vshr.u32	q14, q12, #17
1000	vshr.u32	q4, q11, #17
1001	vshl.u32	q0, q11, #32-17
1002	vst1.u32	{q11}, [r1]!
1003	veor.u32	q4, q4, q0
1004	vshr.u32	q0, q11, #19
1005	vshl.u32	q1, q11, #32-19
1006	veor.u32	q4, q4, q0
1007	vst1.u32	{q12}, [r1]!
1008	veor.u32	q4, q4, q1
1009	vshr.u32	q1, q11, #10
1010	vshl.u32	q0, q12, #32-17
1011	veor.u32	q4, q4, q1
1012	veor.u32	q14, q14, q0
1013	vadd.u32	q13, q13, q4
1014	vshr.u32	q0, q12, #19
1015	vshl.u32	q1, q12, #32-19
1016	veor.u32	q14, q14, q0
1017	vst1.u32	{q13}, [r1]!
1018	veor.u32	q14, q14, q1
1019	vshr.u32	q1, q12, #10
1020
1021	vshr.u32	q4, q13, #17
1022	vshl.u32	q0, q13, #32-17
1023	veor.u32	q14, q14, q1
1024	veor.u32	q4, q4, q0
1025	vshr.u32	q0, q13, #19
1026	vshl.u32	q1, q13, #32-19
1027	veor.u32	q4, q4, q0
1028	vst1.u32	{q14}, [r1]!
1029	veor.u32	q4, q4, q1
1030	vshr.u32	q1, q13, #10
1031	vld1.u32	{q15}, [r1]
1032	veor.u32	q4, q4, q1
1033	vst1.u32	{q15}, [sp]!
1034	vadd.u32	q15, q15, q4
1035	vshr.u32	q4, q14, #17
1036	vshl.u32	q0, q14, #32-17
1037	vshl.u32	q1, q14, #32-19
1038	veor.u32	q4, q4, q0
1039	vshr.u32	q0, q14, #19
1040	vst1.u32	{q15}, [r1]!
1041	veor.u32	q4, q4, q0
1042	vld1.u32	{q9}, [r1]
1043	veor.u32	q4, q4, q1
1044	vshr.u32	q1, q14, #10
1045	vst1.u32	{q9}, [sp]!
1046	veor.u32	q5, q4, q1
1047
1048	vshr.u32	q4, q15, #17
1049	vadd.u32	q9, q9, q5
1050	vshl.u32	q0, q15, #32-17
1051	vshl.u32	q1, q15, #32-19
1052	veor.u32	q4, q4, q0
1053	vshr.u32	q0, q15, #19
1054	vst1.u32	{q9}, [r1]!
1055	veor.u32	q4, q4, q0
1056	vld1.u32	{q10}, [r1]
1057	veor.u32	q4, q4, q1
1058	vshr.u32	q1, q15, #10
1059	vst1.u32	{q10}, [sp]!
1060	veor.u32	q4, q4, q1
1061	vshl.u32	q0, q9, #32-17
1062	vadd.u32	q10, q10, q4
1063	vshr.u32	q4, q9, #17
1064	vshl.u32	q1, q9, #32-19
1065	veor.u32	q4, q4, q0
1066	vshr.u32	q0, q9, #19
1067	veor.u32	q4, q4, q1
1068	vshr.u32	q1, q9, #10
1069	veor.u32	q4, q4, q0
1070	vst1.u32	{q10}, [r1]!
1071	veor.u32	q5, q4, q1
1072
1073	vshr.u32	q4, q10, #17
1074	vshl.u32	q0, q10, #32-17
1075	vadd.u32	q11, q11, q5
1076	veor.u32	q4, q4, q0
1077	vshr.u32	q0, q10, #19
1078	vshl.u32	q1, q10, #32-19
1079	veor.u32	q4, q4, q0
1080	vst1.u32	{q11}, [r1]!
1081	veor.u32	q4, q4, q1
1082	vshr.u32	q1, q10, #10
1083	vshl.u32	q0, q11, #32-17
1084	veor.u32	q2, q4, q1
1085	vshr.u32	q4, q11, #17
1086	vadd.u32	q12, q12, q2
1087	vshl.u32	q1, q11, #32-19
1088	veor.u32	q4, q4, q0
1089	vshr.u32	q0, q11, #19
1090	veor.u32	q4, q4, q1
1091	vshr.u32	q1, q11, #10
1092	veor.u32	q4, q4, q0
1093	vst1.u32	{q12}, [r1]!
1094	veor.u32	q5, q4, q1
1095
1096	vshr.u32	q4, q12, #17
1097	vshl.u32	q0, q12, #32-17
1098	vadd.u32	q13, q13, q5
1099	veor.u32	q4, q4, q0
1100	vshr.u32	q0, q12, #19
1101	vshl.u32	q1, q12, #32-19
1102	veor.u32	q4, q4, q0
1103	vst1.u32	{q13}, [r1]!
1104	veor.u32	q4, q4, q1
1105	vshr.u32	q1, q12, #10
1106	vshl.u32	q0, q13, #32-17
1107	veor.u32	q2, q4, q1
1108	vshr.u32	q4, q13, #17
1109	vadd.u32	q14, q14, q2
1110	vshl.u32	q1, q13, #32-19
1111	veor.u32	q4, q4, q0
1112	vshr.u32	q0, q13, #19
1113	veor.u32	q4, q4, q1
1114	vshr.u32	q1, q13, #10
1115	veor.u32	q4, q4, q0
1116	vst1.u32	{q14}, [r1]!
1117	veor.u32	q5, q4, q1
1118	add	r4, r4, #12*16
1119
1120	vshr.u32	q4, q14, #17
1121	vshl.u32	q0, q14, #32-17
1122	vadd.u32	q15, q15, q5
1123	veor.u32	q4, q4, q0
1124	vshr.u32	q0, q14, #19
1125	vshl.u32	q1, q14, #32-19
1126	veor.u32	q4, q4, q0
1127	vst1.u32	{q15}, [r1]!
1128	veor.u32	q4, q4, q1
1129	vshr.u32	q1, q14, #10
1130	vld1.u32	{q2}, [r1]
1131	veor.u32	q4, q4, q1
1132	vshl.u32	q0, q15, #32-17
1133	vadd.u32	q9, q9, q4
1134	vst1.u32	{q2}, [sp]!
1135	vadd.u32	q9, q9, q2
1136	vshr.u32	q4, q15, #17
1137	vshr.u32	q2, q15, #19
1138	veor.u32	q4, q4, q0
1139	vst1.u32	{q9}, [r1]!
1140	vshl.u32	q1, q15, #32-19
1141	veor.u32	q4, q4, q2
1142	vshr.u32	q0, q15, #10
1143	veor.u32	q4, q4, q1
1144	vld1.u32	{q5-q6}, [r4]!
1145	veor.u32	q4, q4, q0
1146	vld1.u32	{q2}, [r1]
1147	vadd.u32	q10, q10, q4
1148	vst1.u32	{q2}, [sp]!
1149	vadd.u32	q10, q10, q2
1150
1151	sub	sp, sp, #8*16
1152
1153sha256d_ms_4way_extend_loop2:
1154	sha256_4way_extend_doubleround_body 16, r4, r1, q11, q12,  q9, q10
1155	sha256_4way_extend_doubleround_body 18, r4, r1, q13, q14, q11, q12
1156	sha256_4way_extend_doubleround_body 20, r4, r1, q15,  q9, q13, q14
1157	sha256_4way_extend_doubleround_body 22, r4, r1, q10, q11, q15,  q9
1158	sha256_4way_extend_doubleround_body 24, r4, r1, q12, q13, q10, q11
1159	sha256_4way_extend_doubleround_body 26, r4, r1, q14, q15, q12, q13
1160	sha256_4way_extend_doubleround_body 28, r4, r1,  q9, q10, q14, q15
1161	sha256_4way_extend_doubleround_body 30, r4, r1, q11, q12,  q9, q10
1162	sha256_4way_extend_doubleround_body 32, r4, r1, q13, q14, q11, q12
1163	sha256_4way_extend_doubleround_body 34, r4, r1, q15,  q9, q13, q14
1164	sha256_4way_extend_doubleround_body 36, r4, r1, q10, q11, q15,  q9
1165	sha256_4way_extend_doubleround_body 38, r4, r1, q12, q13, q10, q11
1166	sha256_4way_extend_doubleround_body 40, r4, r1, q14, q15, q12, q13
1167	sha256_4way_extend_doubleround_body 42, r4, r1,  q9, q10, q14, q15
1168	sha256_4way_extend_doubleround_body 44, r4, r1, q11, q12,  q9, q10
1169	sha256_4way_extend_doubleround_foot 46, r4, r1, q13, q14, q11, q12
1170	bne	sha256d_ms_4way_extend_coda2
1171
1172	vldmia	r3!, {q4-q7}
1173	vldmia	r3, {q0-q3}
1174	vswp	q0, q4
1175	adr	r3, sha256d_ms_4way_4k+3*16
1176	sub r1, r1, #(64-3)*16
1177	b	sha256d_ms_4way_main_loop1
1178
1179	.align 4
1180sha256d_ms_4way_4k:
1181	sha256_4k
1182
1183sha256d_ms_4way_main_loop2:
1184	sha256_4way_main_round  0, r3, r1, q0, q1, q2, q3, q4, q5, q6, q7
1185	sha256_4way_main_round  1, r3, r1, q3, q0, q1, q2, q7, q4, q5, q6
1186	sha256_4way_main_round  2, r3, r1, q2, q3, q0, q1, q6, q7, q4, q5
1187sha256d_ms_4way_main_loop1:
1188	sha256_4way_main_round  3, r3, r1, q1, q2, q3, q0, q5, q6, q7, q4
1189	sha256_4way_main_quadround  4, r3, r1
1190	sha256_4way_main_quadround  8, r3, r1
1191	sha256_4way_main_quadround 12, r3, r1
1192	sha256_4way_main_quadround 16, r3, r1
1193	sha256_4way_main_quadround 20, r3, r1
1194	sha256_4way_main_quadround 24, r3, r1
1195	sha256_4way_main_quadround 28, r3, r1
1196	sha256_4way_main_quadround 32, r3, r1
1197	sha256_4way_main_quadround 36, r3, r1
1198	sha256_4way_main_quadround 40, r3, r1
1199	sha256_4way_main_quadround 44, r3, r1
1200	sha256_4way_main_quadround 48, r3, r1
1201	sha256_4way_main_quadround 52, r3, r1
1202	sha256_4way_main_round 56, r3, r1, q0, q1, q2, q3, q4, q5, q6, q7
1203	bne	sha256d_ms_4way_finish
1204	sha256_4way_main_round 57, r3, r1, q3, q0, q1, q2, q7, q4, q5, q6
1205	sha256_4way_main_round 58, r3, r1, q2, q3, q0, q1, q6, q7, q4, q5
1206	sha256_4way_main_round 59, r3, r1, q1, q2, q3, q0, q5, q6, q7, q4
1207	sha256_4way_main_quadround 60, r3, r1
1208
1209	vldmia	r2, {q8-q15}
1210	vadd.u32	q0, q0, q8
1211	vadd.u32	q1, q1, q9
1212	vadd.u32	q2, q2, q10
1213	vadd.u32	q3, q3, q11
1214	vadd.u32	q4, q4, q12
1215	vadd.u32	q5, q5, q13
1216	vadd.u32	q6, q6, q14
1217	vadd.u32	q7, q7, q15
1218
1219	vldmia	sp, {q8-q15}
1220	sub	r1, r1, #(64-18)*16
1221	vstmia	r1, {q8-q10}
1222	add	r1, r1, #4*16
1223	vstmia	r1, {q11-q13}
1224	add	r1, r1, #8*16
1225	vstmia	r1, {q14-q15}
1226
1227	vstmia	sp, {q0-q7}
1228	vmov.u32	q8,  #0x80000000
1229	vmov.u32	q9,  #0
1230	vmov.u32	q10, #0
1231	vmov.u32	q11, #0
1232	vmov.u32	q12, #0
1233	vmov.u32	q13, #0
1234	vmov.u32	q14, #0
1235	vmov.u32	q15, #0x00000100
1236	add	r1, sp, #8*16
1237	vstmia	r1!, {q8-q15}
1238	adds	r4, sp, #2*16
1239
1240	vshr.u32	q9, q1, #7
1241	vshl.u32	q2, q1, #32-7
1242	vshr.u32	q4, q1, #18
1243	veor.u32	q9, q9, q2
1244	vshl.u32	q3, q1, #32-18
1245	veor.u32	q9, q9, q4
1246	vshr.u32	q2, q1, #3
1247	veor.u32	q9, q9, q3
1248	vld1.u32	{q5}, [r4]!
1249	veor.u32	q9, q9, q2
1250	vmov.u32	q7, #0x00a00000
1251	vadd.u32	q9, q9, q0
1252	vshr.u32	q10, q5, #7
1253	vshl.u32	q0, q5, #32-7
1254	vshl.u32	q3, q5, #32-18
1255	veor.u32	q10, q10, q0
1256	vshr.u32	q0, q5, #18
1257	veor.u32	q10, q10, q3
1258	vst1.u32	{q9}, [r1]!
1259	vadd.u32	q3, q1, q7
1260	veor.u32	q10, q10, q0
1261	vshr.u32	q0, q5, #3
1262	vld1.u32	{q6}, [r4]!
1263	veor.u32	q10, q10, q0
1264
1265	vshr.u32	q4, q9, #17
1266	vshl.u32	q0, q9, #32-17
1267	vadd.u32	q10, q10, q3
1268	veor.u32	q4, q4, q0
1269	vshr.u32	q0, q9, #19
1270	vshl.u32	q1, q9, #32-19
1271	veor.u32	q4, q4, q0
1272	vshr.u32	q11, q6, #7
1273	vshl.u32	q0, q6, #32-7
1274	veor.u32	q4, q4, q1
1275	veor.u32	q11, q11, q0
1276	vshr.u32	q1, q9, #10
1277	vshr.u32	q0, q6, #18
1278	veor.u32	q4, q4, q1
1279	veor.u32	q11, q11, q0
1280	vshl.u32	q1, q6, #32-18
1281	vshr.u32	q0, q6, #3
1282	veor.u32	q11, q11, q1
1283	vadd.u32	q4, q4, q5
1284	veor.u32	q11, q11, q0
1285	vld1.u32	{q5}, [r4]!
1286	vadd.u32	q11, q11, q4
1287	vshr.u32	q4, q10, #17
1288	vshl.u32	q0, q10, #32-17
1289	vst1.u32	{q10}, [r1]!
1290	veor.u32	q4, q4, q0
1291	vshr.u32	q0, q10, #19
1292	vshl.u32	q1, q10, #32-19
1293	veor.u32	q4, q4, q0
1294	vshr.u32	q12, q5, #7
1295	veor.u32	q4, q4, q1
1296	vshl.u32	q0, q5, #32-7
1297	vshr.u32	q1, q10, #10
1298	veor.u32	q12, q12, q0
1299	vshr.u32	q0, q5, #18
1300	veor.u32	q4, q4, q1
1301	veor.u32	q12, q12, q0
1302	vshl.u32	q1, q5, #32-18
1303	vst1.u32	{q11}, [r1]!
1304	veor.u32	q12, q12, q1
1305	vshr.u32	q0, q5, #3
1306	vadd.u32	q1, q6, q4
1307	veor.u32	q12, q12, q0
1308
1309	vshr.u32	q4, q11, #17
1310	vshl.u32	q0, q11, #32-17
1311	vadd.u32	q12, q12, q1
1312	vld1.u32	{q6}, [r4]!
1313	veor.u32	q4, q4, q0
1314	vshr.u32	q0, q11, #19
1315	vshl.u32	q1, q11, #32-19
1316	veor.u32	q4, q4, q0
1317	vshr.u32	q13, q6, #7
1318	vshl.u32	q0, q6, #32-7
1319	veor.u32	q4, q4, q1
1320	veor.u32	q13, q13, q0
1321	vshr.u32	q1, q11, #10
1322	vshr.u32	q0, q6, #18
1323	veor.u32	q4, q4, q1
1324	veor.u32	q13, q13, q0
1325	vshl.u32	q1, q6, #32-18
1326	vshr.u32	q0, q6, #3
1327	veor.u32	q13, q13, q1
1328	vadd.u32	q4, q4, q5
1329	veor.u32	q13, q13, q0
1330	vld1.u32	{q5}, [r4]!
1331	vadd.u32	q13, q13, q4
1332	vshr.u32	q4, q12, #17
1333	vshl.u32	q0, q12, #32-17
1334	vst1.u32	{q12}, [r1]!
1335	veor.u32	q4, q4, q0
1336	vshr.u32	q0, q12, #19
1337	vshl.u32	q1, q12, #32-19
1338	veor.u32	q4, q4, q0
1339	vshr.u32	q14, q5, #7
1340	veor.u32	q4, q4, q1
1341	vshl.u32	q0, q5, #32-7
1342	vshr.u32	q1, q12, #10
1343	veor.u32	q14, q14, q0
1344	vshr.u32	q0, q5, #18
1345	veor.u32	q4, q4, q1
1346	veor.u32	q14, q14, q0
1347	vshl.u32	q1, q5, #32-18
1348	vst1.u32	{q13}, [r1]!
1349	veor.u32	q14, q14, q1
1350	vshr.u32	q0, q5, #3
1351	vadd.u32	q1, q6, q4
1352	veor.u32	q14, q14, q0
1353
1354	vshr.u32	q4, q13, #17
1355	vshl.u32	q0, q13, #32-17
1356	vadd.u32	q14, q14, q1
1357	vld1.u32	{q6}, [r4]!
1358	vadd.u32	q5, q5, q15
1359	veor.u32	q4, q4, q0
1360	vshr.u32	q0, q13, #19
1361	vshl.u32	q1, q13, #32-19
1362	veor.u32	q4, q4, q0
1363	vshr.u32	q15, q6, #7
1364	vshl.u32	q0, q6, #32-7
1365	veor.u32	q4, q4, q1
1366	veor.u32	q15, q15, q0
1367	vshr.u32	q1, q13, #10
1368	vshr.u32	q0, q6, #18
1369	veor.u32	q4, q4, q1
1370	veor.u32	q15, q15, q0
1371	vshl.u32	q1, q6, #32-18
1372	vshr.u32	q0, q6, #3
1373	veor.u32	q15, q15, q1
1374	vadd.u32	q4, q4, q5
1375	veor.u32	q15, q15, q0
1376	vmov.u32	q5, #0x80000000
1377	vadd.u32	q15, q15, q4
1378	vshr.u32	q4, q14, #17
1379	vshl.u32	q0, q14, #32-17
1380	vadd.u32	q6, q6, q9
1381	vst1.u32	{q14}, [r1]!
1382	vmov.u32	q7, #0x11000000
1383	veor.u32	q4, q4, q0
1384	vshr.u32	q0, q14, #19
1385	vshl.u32	q1, q14, #32-19
1386	vadd.u32	q6, q6, q7
1387	vmov.u32	q2, #0x00002000
1388	veor.u32	q4, q4, q0
1389	vst1.u32	{q15}, [r1]!
1390	veor.u32	q4, q4, q1
1391	vshr.u32	q1, q14, #10
1392	vadd.u32	q6, q6, q2
1393	veor.u32	q1, q4, q1
1394	add	r4, r4, #8*16
1395
1396	vshr.u32	q4, q15, #17
1397	vshl.u32	q0, q15, #32-17
1398	vadd.u32	q9, q6, q1
1399	veor.u32	q4, q4, q0
1400	vshr.u32	q0, q15, #19
1401	vshl.u32	q1, q15, #32-19
1402	veor.u32	q4, q4, q0
1403	vst1.u32	{q9}, [r1]!
1404	vadd.u32	q5, q5, q10
1405	veor.u32	q4, q4, q1
1406	vshr.u32	q1, q15, #10
1407	vshl.u32	q0, q9, #32-17
1408	veor.u32	q10, q4, q1
1409	vshr.u32	q4, q9, #17
1410	vadd.u32	q10, q10, q5
1411	veor.u32	q4, q4, q0
1412	vshr.u32	q0, q9, #19
1413	vshl.u32	q1, q9, #32-19
1414	veor.u32	q4, q4, q0
1415	vshr.u32	q0, q9, #10
1416	veor.u32	q4, q4, q1
1417	vst1.u32	{q10}, [r1]!
1418	veor.u32	q1, q4, q0
1419
1420	vshr.u32	q4, q10, #17
1421	vshl.u32	q0, q10, #32-17
1422	vadd.u32	q11, q11, q1
1423	veor.u32	q4, q4, q0
1424	vshr.u32	q0, q10, #19
1425	vshl.u32	q1, q10, #32-19
1426	veor.u32	q4, q4, q0
1427	vst1.u32	{q11}, [r1]!
1428	veor.u32	q4, q4, q1
1429	vshr.u32	q1, q10, #10
1430	vshl.u32	q0, q11, #32-17
1431	veor.u32	q1, q4, q1
1432	vshr.u32	q4, q11, #17
1433	vadd.u32	q12, q12, q1
1434	veor.u32	q4, q4, q0
1435	vshr.u32	q0, q11, #19
1436	vshl.u32	q1, q11, #32-19
1437	veor.u32	q4, q4, q0
1438	vshr.u32	q0, q11, #10
1439	veor.u32	q4, q4, q1
1440	vst1.u32	{q12}, [r1]!
1441	veor.u32	q1, q4, q0
1442
1443	vshr.u32	q4, q12, #17
1444	vshl.u32	q0, q12, #32-17
1445	vadd.u32	q13, q13, q1
1446	veor.u32	q4, q4, q0
1447	vshr.u32	q0, q12, #19
1448	vshl.u32	q1, q12, #32-19
1449	veor.u32	q4, q4, q0
1450	vst1.u32	{q13}, [r1]!
1451	veor.u32	q4, q4, q1
1452	vshr.u32	q1, q12, #10
1453	vshl.u32	q0, q13, #32-17
1454	veor.u32	q1, q4, q1
1455	vshr.u32	q4, q13, #17
1456	vadd.u32	q14, q14, q1
1457	veor.u32	q4, q4, q0
1458	vshr.u32	q0, q13, #19
1459	vshl.u32	q1, q13, #32-19
1460	veor.u32	q4, q4, q0
1461	vshr.u32	q0, q13, #10
1462	veor.u32	q4, q4, q1
1463	vst1.u32	{q14}, [r1]!
1464	veor.u32	q4, q4, q0
1465	vmov.u32	q6, #0x00000100
1466	vadd.u32	q15, q15, q4
1467
1468	vshr.u32	q4, q14, #17
1469	vshl.u32	q0, q14, #32-17
1470	vmov.u32	q7, #0x00400000
1471	vst1.u32	{q15}, [r1]!
1472	veor.u32	q4, q4, q0
1473	vshr.u32	q0, q14, #19
1474	vshl.u32	q1, q14, #32-19
1475	veor.u32	q4, q4, q0
1476	vadd.u32	q9, q9, q7
1477	veor.u32	q4, q4, q1
1478	vshr.u32	q1, q14, #10
1479	vmov.u32	q2, #0x00000022
1480	veor.u32	q4, q4, q1
1481	vadd.u32	q9, q9, q2
1482	vld1.u32	{q5}, [r4]!
1483	vadd.u32	q9, q9, q4
1484	vshr.u32	q4, q15, #17
1485	vshl.u32	q0, q15, #32-17
1486	vadd.u32	q6, q6, q10
1487	vst1.u32	{q9}, [r1]!
1488	veor.u32	q4, q4, q0
1489	vshr.u32	q0, q15, #19
1490	vshl.u32	q1, q15, #32-19
1491	veor.u32	q4, q4, q0
1492	vshr.u32	q10, q5, #7
1493	veor.u32	q4, q4, q1
1494	vshl.u32	q0, q5, #32-7
1495	vshr.u32	q1, q15, #10
1496	veor.u32	q10, q10, q0
1497	vshr.u32	q0, q5, #18
1498	veor.u32	q4, q4, q1
1499	veor.u32	q10, q10, q0
1500	vshl.u32	q1, q5, #32-18
1501	vshr.u32	q0, q5, #3
1502	veor.u32	q10, q10, q1
1503	vadd.u32	q1, q6, q4
1504	veor.u32	q10, q10, q0
1505	vld1.u32	{q6}, [r4]!
1506	vadd.u32	q10, q10, q1
1507
1508	b	sha256d_ms_4way_extend_loop2
1509
1510	.align 4
1511sha256d_ms_4way_4h:
1512	.long 0x6a09e667, 0x6a09e667, 0x6a09e667, 0x6a09e667
1513	.long 0xbb67ae85, 0xbb67ae85, 0xbb67ae85, 0xbb67ae85
1514	.long 0x3c6ef372, 0x3c6ef372, 0x3c6ef372, 0x3c6ef372
1515	.long 0xa54ff53a, 0xa54ff53a, 0xa54ff53a, 0xa54ff53a
1516	.long 0x510e527f, 0x510e527f, 0x510e527f, 0x510e527f
1517	.long 0x9b05688c, 0x9b05688c, 0x9b05688c, 0x9b05688c
1518	.long 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab
1519	.long 0x5be0cd19, 0x5be0cd19, 0x5be0cd19, 0x5be0cd19
1520
1521sha256d_ms_4way_extend_coda2:
1522	adr	r4, sha256d_ms_4way_4h
1523	mov	r1, sp
1524	vldmia	r4, {q0-q7}
1525	vmov.u32	q15, q7
1526	sub	r3, r3, #64*16
1527	b	sha256d_ms_4way_main_loop2
1528
1529.macro sha256_4way_main_round_red i, rk, rw, rd, re, rf, rg, rh
1530	vld1.u32	{q8}, [\rw]!
1531	vand.u32	q9, \rf, \re
1532	vbic.u32	q10, \rg, \re
1533	vshr.u32	q11, \re, #5
1534	vorr.u32	q10, q10, q9
1535	vshl.u32	q12, \re, #32-5
1536	vadd.u32	\rh, \rh, q10
1537	veor.u32	q10, \re, q11
1538	vshr.u32	q11, \re, #19
1539	veor.u32	q10, q10, q12
1540	vshl.u32	q12, \re, #32-19
1541	veor.u32	q10, q10, q11
1542	vadd.u32	\rh, \rh, q8
1543	veor.u32	q10, q10, q12
1544	vld1.u32	{q9}, [\rk]!
1545	vadd.u32	\rh, \rh, \rd
1546	vshr.u32	q11, q10, #6
1547	vadd.u32	\rh, \rh, q9
1548	vshl.u32	q13, q10, #32-6
1549	vadd.u32	\rh, \rh, q11
1550	vadd.u32	\rh, \rh, q13
1551.endm
1552
1553sha256d_ms_4way_finish:
1554	sha256_4way_main_round_red 57, r3, r1, q2, q7, q4, q5, q6
1555	sha256_4way_main_round_red 58, r3, r1, q1, q6, q7, q4, q5
1556	sha256_4way_main_round_red 59, r3, r1, q0, q5, q6, q7, q4
1557	sha256_4way_main_round_red 60, r3, r1, q3, q4, q5, q6, q7
1558
1559	vadd.u32	q7, q7, q15
1560	add	r0, r0, #7*16
1561	vst1.u32	{q7}, [r0]
1562
1563	mov	sp, r12
1564	vpop	{q4-q7}
1565	ldmfd	sp!, {r4, pc}
1566
1567
1568	.text
1569	.code 32
1570	.align 2
1571	.globl sha256_use_4way
1572	.globl _sha256_use_4way
1573#ifdef __ELF__
1574	.type sha256_use_4way, %function
1575#endif
1576sha256_use_4way:
1577_sha256_use_4way:
1578	mov	r0, #1
1579	bx	lr
1580
1581#endif /* __ARM_NEON__ */
1582
1583#endif
1584