sha/asm/keccak1600-armv4.pl: optimization based on profiler feedback.
[openssl.git] / crypto / sha / asm / keccak1600-armv4.pl
1 my @C = map("r$_",(0..9));
2 my @E = map("r$_",(10..12,14));
3
4 my @A = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (0,5,10,15,20));
5 my @D = map(8*$_, (25..29));
6 my @T = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (30,35));
7
8 $code.=<<___;
9 .text
10
11 .type   iotas,%object
12 .align  5
13 iotas:
14         .long   0x00000001, 0x00000000
15         .long   0x00000000, 0x00000089
16         .long   0x00000000, 0x8000008b
17         .long   0x00000000, 0x80008080
18         .long   0x00000001, 0x0000008b
19         .long   0x00000001, 0x00008000
20         .long   0x00000001, 0x80008088
21         .long   0x00000001, 0x80000082
22         .long   0x00000000, 0x0000000b
23         .long   0x00000000, 0x0000000a
24         .long   0x00000001, 0x00008082
25         .long   0x00000000, 0x00008003
26         .long   0x00000001, 0x0000808b
27         .long   0x00000001, 0x8000000b
28         .long   0x00000001, 0x8000008a
29         .long   0x00000001, 0x80000081
30         .long   0x00000000, 0x80000081
31         .long   0x00000000, 0x80000008
32         .long   0x00000000, 0x00000083
33         .long   0x00000000, 0x80008003
34         .long   0x00000001, 0x80008088
35         .long   0x00000000, 0x80000088
36         .long   0x00000001, 0x00008000
37         .long   0x00000000, 0x80008082
38 .size   iostas,.-iotas
39
40 .global KeccakF1600
41 .type   KeccakF1600, %function
42 .align  5
43 KeccakF1600:
44         eor     r1,r1,r1
45         stmdb   sp!,{r0,r1,r4-r12,lr}
46         sub     sp,sp,#320                      @ space for A[5][5],D[5],T[2][5]
47
48         add     @E[0],r0,#$A[1][0]
49         add     @E[1],sp,#$A[1][0]
50         mov     @E[2],r0
51         ldmia   @E[0]!,{@C[0]-@C[9]}            @ copy A[5][5] to stack
52         stmia   @E[1]!,{@C[0]-@C[9]}
53         ldmia   @E[0]!,{@C[0]-@C[9]}
54         stmia   @E[1]!,{@C[0]-@C[9]}
55         ldmia   @E[0]!,{@C[0]-@C[9]}
56         stmia   @E[1]!,{@C[0]-@C[9]}
57         ldmia   @E[0],{@C[0]-@C[9]}
58         stmia   @E[1],{@C[0]-@C[9]}
59         ldmia   @E[2],{@C[0]-@C[9]}
60         stmia   sp,{@C[0]-@C[9]}
61         add     @E[0],sp,#$A[1][0]
62         b       .Lround
63
64 .align  4
65 .Lround:
66         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[1][0..1]
67         eor     @C[0],@C[0],@E[0]
68          add    @E[0],sp,#$A[1][2]
69         eor     @C[1],@C[1],@E[1]
70         eor     @C[2],@C[2],@E[2]
71         eor     @C[3],@C[3],@E[3]
72         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[1][2..3]
73         eor     @C[4],@C[4],@E[0]
74          add    @E[0],sp,#$A[1][4]
75         eor     @C[5],@C[5],@E[1]
76         eor     @C[6],@C[6],@E[2]
77         eor     @C[7],@C[7],@E[3]
78         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[1][4]..A[2][0]
79         eor     @C[8],@C[8],@E[0]
80          add    @E[0],sp,#$A[2][1]
81         eor     @C[9],@C[9],@E[1]
82         eor     @C[0],@C[0],@E[2]
83         eor     @C[1],@C[1],@E[3]
84         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[2][1..2]
85         eor     @C[2],@C[2],@E[0]
86          add    @E[0],sp,#$A[2][3]
87         eor     @C[3],@C[3],@E[1]
88         eor     @C[4],@C[4],@E[2]
89         eor     @C[5],@C[5],@E[3]
90         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[2][3..4]
91         eor     @C[6],@C[6],@E[0]
92          add    @E[0],sp,#$A[3][0]
93         eor     @C[7],@C[7],@E[1]
94         eor     @C[8],@C[8],@E[2]
95         eor     @C[9],@C[9],@E[3]
96         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[3][0..1]
97         eor     @C[0],@C[0],@E[0]
98          add    @E[0],sp,#$A[3][2]
99         eor     @C[1],@C[1],@E[1]
100         eor     @C[2],@C[2],@E[2]
101         eor     @C[3],@C[3],@E[3]
102         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[3][2..3]
103         eor     @C[4],@C[4],@E[0]
104          add    @E[0],sp,#$A[3][4]
105         eor     @C[5],@C[5],@E[1]
106         eor     @C[6],@C[6],@E[2]
107         eor     @C[7],@C[7],@E[3]
108         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[3][4]..A[4][0]
109         eor     @C[8],@C[8],@E[0]
110          add    @E[0],sp,#$A[4][1]
111         eor     @C[9],@C[9],@E[1]
112         eor     @C[0],@C[0],@E[2]
113         eor     @C[1],@C[1],@E[3]
114         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[4][1..2]
115         eor     @C[2],@C[2],@E[0]
116          add    @E[0],sp,#$A[4][3]
117         eor     @C[3],@C[3],@E[1]
118         eor     @C[4],@C[4],@E[2]
119         eor     @C[5],@C[5],@E[3]
120         ldmia   @E[0],{@E[0]-@E[2],@E[3]}       @ A[4][3..4]
121         eor     @C[6],@C[6],@E[0]
122         eor     @C[7],@C[7],@E[1]
123         eor     @C[8],@C[8],@E[2]
124         eor     @C[9],@C[9],@E[3]
125
126         eor     @E[0],@C[0],@C[5],ror#32-1      @ E[0] = ROL64(C[2], 1) ^ C[0];
127         eor     @E[1],@C[1],@C[4]
128         str     @E[0],[sp,#$D[1]]               @ D[1] = E[0]
129         eor     @E[2],@C[6],@C[1],ror#32-1      @ E[1] = ROL64(C[0], 1) ^ C[3];
130         str     @E[1],[sp,#$D[1]+4]
131         eor     @E[3],@C[7],@C[0]
132         str     @E[2],[sp,#$D[4]]               @ D[4] = E[1]
133         eor     @C[0],@C[8],@C[3],ror#32-1      @ C[0] = ROL64(C[1], 1) ^ C[4];
134         str     @E[3],[sp,#$D[4]+4]
135         eor     @C[1],@C[9],@C[2]
136         str     @C[0],[sp,#$D[0]]               @ D[0] = C[0]
137         eor     @C[2],@C[2],@C[7],ror#32-1      @ C[1] = ROL64(C[3], 1) ^ C[1];
138         str     @C[1],[sp,#$D[0]+4]
139         eor     @C[3],@C[3],@C[6]
140         str     @C[2],[sp,#$D[2]]               @ D[2] = C[1]
141         eor     @C[4],@C[4],@C[9],ror#32-1      @ C[2] = ROL64(C[4], 1) ^ C[2];
142         str     @C[3],[sp,#$D[2]+4]
143         eor     @C[5],@C[5],@C[8]
144         str     @C[4],[sp,#$D[3]]               @ D[3] = C[2]
145         str     @C[5],[sp,#$D[3]+4]
146
147         ldr     @C[8],[sp,#$A[3][0]]
148         ldr     @C[9],[sp,#$A[3][0]+4]
149         ldr     @C[6],[sp,#$A[0][1]]
150         ldr     @C[7],[sp,#$A[0][1]+4]
151         eor     @C[8],@C[8],@C[0]
152         eor     @C[9],@C[9],@C[1]
153         str     @C[8],[sp,#$T[0][0]]            @ T[0][0] = A[3][0] ^ C[0]; /* borrow T[0][0] */
154         ldr     @C[8],[sp,#$A[0][2]]
155         str     @C[9],[sp,#$T[0][0]+4]
156         ldr     @C[9],[sp,#$A[0][2]+4]
157         eor     @C[6],@C[6],@E[0]
158         eor     @C[7],@C[7],@E[1]
159         str     @C[6],[sp,#$T[0][1]]            @ T[0][1] = A[0][1] ^ E[0]; /* D[1] */
160         ldr     @C[6],[sp,#$A[0][3]]
161         str     @C[7],[sp,#$T[0][1]+4]
162         ldr     @C[7],[sp,#$A[0][3]+4]
163         eor     @C[8],@C[8],@C[2]
164         eor     @C[9],@C[9],@C[3]
165         str     @C[8],[sp,#$T[0][2]]            @ T[0][2] = A[0][2] ^ C[1]; /* D[2] */
166         ldr     @C[8],[sp,#$A[0][4]]
167         str     @C[9],[sp,#$T[0][2]+4]
168         ldr     @C[9],[sp,#$A[0][4]+4]
169         eor     @C[6],@C[6],@C[4]
170         eor     @C[7],@C[7],@C[5]
171         str     @C[6],[sp,#$T[0][3]]            @ T[0][3] = A[0][3] ^ C[2]; /* D[3] */
172         eor     @C[8],@C[8],@E[2]
173         str     @C[7],[sp,#$T[0][3]+4]
174         eor     @C[9],@C[9],@E[3]
175         str     @C[8],[sp,#$T[0][4]]            @ T[0][4] = A[0][4] ^ E[1]; /* D[4] */
176         str     @C[9],[sp,#$T[0][4]+4]
177
178         ldr     @C[6],[sp,#$A[3][3]]
179         ldr     @C[7],[sp,#$A[3][3]+4]
180         ldr     @C[8],[sp,#$A[4][4]]
181         ldr     @C[9],[sp,#$A[4][4]+4]
182         eor     @C[4],@C[4],@C[6]
183         eor     @C[5],@C[5],@C[7]
184         ror     @C[7],@C[4],#32-10              @ C[3] = ROL64(A[3][3] ^ C[2], rhotates[3][3]);   /* D[3] */
185         ldr     @C[4],[sp,#$A[0][0]]
186         ror     @C[6],@C[5],#32-11
187         ldr     @C[5],[sp,#$A[0][0]+4]
188         eor     @C[8],@C[8],@E[2]
189         eor     @C[9],@C[9],@E[3]
190         ror     @C[8],@C[8],#32-7               @ C[4] = ROL64(A[4][4] ^ E[1], rhotates[4][4]);   /* D[4] */
191         ldr     @E[2],[sp,#$A[2][2]]
192         ror     @C[9],@C[9],#32-7
193         ldr     @E[3],[sp,#$A[2][2]+4]
194         eor     @C[0],@C[0],@C[4]
195         eor     @C[1],@C[1],@C[5]               @ C[0] =       A[0][0] ^ C[0]; /* rotate by 0 */  /* D[0] */
196         eor     @E[2],@E[2],@C[2]
197         ldr     @C[2],[sp,#$A[1][1]]
198         eor     @E[3],@E[3],@C[3]
199         ldr     @C[3],[sp,#$A[1][1]+4]
200         ror     @C[5],@E[2],#32-21              @ C[2] = ROL64(A[2][2] ^ C[1], rhotates[2][2]);   /* D[2] */
201         eor     @C[2],@C[2],@E[0]
202         ror     @C[4],@E[3],#32-22
203          adr    @E[0],iotas
204         eor     @C[3],@C[3],@E[1]
205          ldr    @E[1],[sp,#320+4]               @ load counter
206         ror     @C[2],@C[2],#32-22              @ C[1] = ROL64(A[1][1] ^ E[0], rhotates[1][1]);   /* D[1] */
207         ror     @C[3],@C[3],#32-22
208
209         add     @E[0],@E[0],@E[1]
210         ldr     @E[2],[@E[0],#0]
211         add     @E[1],@E[1],#8
212         ldr     @E[3],[@E[0],#4]
213         cmp     @E[1],#192
214         str     @E[1],[sp,#320+4]               @ store counter
215
216         bic     @E[0],@C[4],@C[2]
217         bic     @E[1],@C[5],@C[3]
218         eor     @E[0],@E[0],@C[0]
219         eor     @E[1],@E[1],@C[1]
220         eor     @E[0],@E[0],@E[2]
221         eor     @E[1],@E[1],@E[3]
222         str     @E[0],[sp,#$A[0][0]]            @ A[0][0] = C[0] ^ (~C[1] & C[2]) ^ iotas[i];
223         bic     @E[2],@C[6],@C[4]
224         str     @E[1],[sp,#$A[0][0]+4]
225         bic     @E[3],@C[7],@C[5]
226         eor     @E[2],@E[2],@C[2]
227         eor     @E[3],@E[3],@C[3]
228         str     @E[2],[sp,#$A[0][1]]            @ A[0][1] = C[1] ^ (~C[2] & C[3]);
229         bic     @E[0],@C[8],@C[6]
230         str     @E[3],[sp,#$A[0][1]+4]
231         bic     @E[1],@C[9],@C[7]
232         eor     @E[0],@E[0],@C[4]
233         eor     @E[1],@E[1],@C[5]
234         str     @E[0],[sp,#$A[0][2]]            @ A[0][2] = C[2] ^ (~C[3] & C[4]);
235         bic     @E[2],@C[0],@C[8]
236         str     @E[1],[sp,#$A[0][2]+4]
237         bic     @E[3],@C[1],@C[9]
238         eor     @E[2],@E[2],@C[6]
239         eor     @E[3],@E[3],@C[7]
240         str     @E[2],[sp,#$A[0][3]]            @ A[0][3] = C[3] ^ (~C[4] & C[0]);
241         bic     @E[0],@C[2],@C[0]
242         str     @E[3],[sp,#$A[0][3]+4]
243          add    @E[3],sp,#$D[0]
244         bic     @E[1],@C[3],@C[1]
245         eor     @E[0],@E[0],@C[8]
246         eor     @E[1],@E[1],@C[9]
247         str     @E[0],[sp,#$A[0][4]]            @ A[0][4] = C[4] ^ (~C[0] & C[1]);
248         str     @E[1],[sp,#$A[0][4]+4]
249
250         ldmia   @E[3],{@C[6]-@C[9],@E[0],@E[1],@E[2],@E[3]}     @ D[0..3]
251         ldr     @C[4],[sp,#$D[4]]
252         ldr     @C[5],[sp,#$D[4]+4]
253         ldr     @C[0],[sp,#$A[1][0]]
254         ldr     @C[1],[sp,#$A[1][0]+4]
255         ldr     @C[2],[sp,#$A[2][1]]
256         ldr     @C[3],[sp,#$A[2][1]+4]
257         eor     @C[0],@C[0],@C[6]
258         eor     @C[1],@C[1],@C[7]
259         str     @C[0],[sp,#$T[1][0]]            @ T[1][0] = A[1][0] ^ (C[3] = D[0]);
260         add     @C[0],sp,#$A[1][2]
261         str     @C[1],[sp,#$T[1][0]+4]
262         eor     @C[2],@C[2],@C[8]
263         eor     @C[3],@C[3],@C[9]
264         str     @C[2],[sp,#$T[1][1]]            @ T[1][1] = A[2][1] ^ (C[4] = D[1]); /* borrow T[1][1] */
265         str     @C[3],[sp,#$T[1][1]+4]
266         ldmia   @C[0],{@C[0]-@C[3]}             @ A[1][2..3]
267         eor     @C[0],@C[0],@E[0]
268         eor     @C[1],@C[1],@E[1]
269         str     @C[0],[sp,#$T[1][2]]            @ T[1][2] = A[1][2] ^ (E[0] = D[2]);
270         ldr     @C[0],[sp,#$A[2][4]]
271         str     @C[1],[sp,#$T[1][2]+4]
272         ldr     @C[1],[sp,#$A[2][4]+4]
273         eor     @C[2],@C[2],@E[2]
274         eor     @C[3],@C[3],@E[3]
275         str     @C[2],[sp,#$T[1][3]]            @ T[1][3] = A[1][3] ^ (E[1] = D[3]);
276          ldr    @C[2],[sp,#$T[0][3]]
277         str     @C[3],[sp,#$T[1][3]+4]
278          ldr    @C[3],[sp,#$T[0][3]+4]
279         eor     @C[0],@C[0],@C[4]
280          ldr    @E[2],[sp,#$A[1][4]]
281         eor     @C[1],@C[1],@C[5]
282          ldr    @E[3],[sp,#$A[1][4]+4]
283         str     @C[0],[sp,#$T[1][4]]            @ T[1][4] = A[2][4] ^ (C[2] = D[4]); /* borrow T[1][4] */
284
285         ror     @C[0],@C[2],#32-14              @ C[0] = ROL64(T[0][3],        rhotates[0][3]);
286          str    @C[1],[sp,#$T[1][4]+4]
287         ror     @C[1],@C[3],#32-14
288         eor     @C[2],@E[2],@C[4]
289         ldr     @C[4],[sp,#$A[2][0]]
290         eor     @C[3],@E[3],@C[5]
291         ldr     @C[5],[sp,#$A[2][0]+4]
292         ror     @C[2],@C[2],#32-10              @ C[1] = ROL64(A[1][4] ^ C[2], rhotates[1][4]);   /* D[4] */
293         ldr     @E[2],[sp,#$A[3][1]]
294         ror     @C[3],@C[3],#32-10
295         ldr     @E[3],[sp,#$A[3][1]+4]
296         eor     @C[6],@C[6],@C[4]
297         eor     @C[7],@C[7],@C[5]
298         ror     @C[5],@C[6],#32-1               @ C[2] = ROL64(A[2][0] ^ C[3], rhotates[2][0]);   /* D[0] */
299         eor     @E[2],@E[2],@C[8]
300         ror     @C[4],@C[7],#32-2
301         ldr     @C[8],[sp,#$A[4][2]]
302         eor     @E[3],@E[3],@C[9]
303         ldr     @C[9],[sp,#$A[4][2]+4]
304         ror     @C[7],@E[2],#32-22              @ C[3] = ROL64(A[3][1] ^ C[4], rhotates[3][1]);   /* D[1] */
305         eor     @E[0],@E[0],@C[8]
306         ror     @C[6],@E[3],#32-23
307         eor     @E[1],@E[1],@C[9]
308         ror     @C[9],@E[0],#32-30              @ C[4] = ROL64(A[4][2] ^ E[0], rhotates[4][2]);   /* D[2] */
309
310         bic     @E[0],@C[4],@C[2]
311          ror    @C[8],@E[1],#32-31
312         bic     @E[1],@C[5],@C[3]
313         eor     @E[0],@E[0],@C[0]
314         eor     @E[1],@E[1],@C[1]
315         str     @E[0],[sp,#$A[1][0]]            @ A[1][0] = C[0] ^ (~C[1] & C[2])
316         bic     @E[2],@C[6],@C[4]
317         str     @E[1],[sp,#$A[1][0]+4]
318         bic     @E[3],@C[7],@C[5]
319         eor     @E[2],@E[2],@C[2]
320         eor     @E[3],@E[3],@C[3]
321         str     @E[2],[sp,#$A[1][1]]            @ A[1][1] = C[1] ^ (~C[2] & C[3]);
322         bic     @E[0],@C[8],@C[6]
323         str     @E[3],[sp,#$A[1][1]+4]
324         bic     @E[1],@C[9],@C[7]
325         eor     @E[0],@E[0],@C[4]
326         eor     @E[1],@E[1],@C[5]
327         str     @E[0],[sp,#$A[1][2]]            @ A[1][2] = C[2] ^ (~C[3] & C[4]);
328         bic     @E[2],@C[0],@C[8]
329         str     @E[1],[sp,#$A[1][2]+4]
330         bic     @E[3],@C[1],@C[9]
331         eor     @E[2],@E[2],@C[6]
332         eor     @E[3],@E[3],@C[7]
333         str     @E[2],[sp,#$A[1][3]]            @ A[1][3] = C[3] ^ (~C[4] & C[0]);
334         bic     @E[0],@C[2],@C[0]
335         str     @E[3],[sp,#$A[1][3]+4]
336          add    @E[3],sp,#$D[3]
337         bic     @E[1],@C[3],@C[1]
338          ldr    @C[1],[sp,#$T[0][1]]
339         eor     @E[0],@E[0],@C[8]
340          ldr    @C[0],[sp,#$T[0][1]+4]
341         eor     @E[1],@E[1],@C[9]
342         str     @E[0],[sp,#$A[1][4]]            @ A[1][4] = C[4] ^ (~C[0] & C[1]);
343         str     @E[1],[sp,#$A[1][4]+4]
344
345         ldr     @C[2],[sp,#$T[1][2]]
346         ldr     @C[3],[sp,#$T[1][2]+4]
347         ldmia   @E[3],{@E[0]-@E[2],@E[3]}       @ D[3..4]
348         ldr     @C[4],[sp,#$A[2][3]]
349         ror     @C[0],@C[0],#32-1               @ C[0] = ROL64(T[0][1],        rhotates[0][1]);
350         ldr     @C[5],[sp,#$A[2][3]+4]
351         ror     @C[2],@C[2],#32-3               @ C[1] = ROL64(T[1][2],        rhotates[1][2]);
352         ldr     @C[6],[sp,#$A[3][4]]
353         ror     @C[3],@C[3],#32-3
354         ldr     @C[7],[sp,#$A[3][4]+4]
355         eor     @E[0],@E[0],@C[4]
356         ldr     @C[8],[sp,#$A[4][0]]
357         eor     @E[1],@E[1],@C[5]
358         ldr     @C[9],[sp,#$A[4][0]+4]
359         ror     @C[5],@E[0],#32-12              @ C[2] = ROL64(A[2][3] ^ D[3], rhotates[2][3]);
360         ldr     @E[0],[sp,#$D[0]]
361         ror     @C[4],@E[1],#32-13
362         ldr     @E[1],[sp,#$D[0]+4]
363         eor     @C[6],@C[6],@E[2]
364         eor     @C[7],@C[7],@E[3]
365         ror     @C[6],@C[6],#32-4               @ C[3] = ROL64(A[3][4] ^ D[4], rhotates[3][4]);
366         eor     @C[8],@C[8],@E[0]
367         ror     @C[7],@C[7],#32-4
368         eor     @C[9],@C[9],@E[1]
369         ror     @C[8],@C[8],#32-9               @ C[4] = ROL64(A[4][0] ^ D[0], rhotates[4][0]);
370
371         bic     @E[0],@C[4],@C[2]
372          ror    @C[9],@C[9],#32-9
373         bic     @E[1],@C[5],@C[3]
374         eor     @E[0],@E[0],@C[0]
375         eor     @E[1],@E[1],@C[1]
376         str     @E[0],[sp,#$A[2][0]]            @ A[2][0] = C[0] ^ (~C[1] & C[2])
377         bic     @E[2],@C[6],@C[4]
378         str     @E[1],[sp,#$A[2][0]+4]
379         bic     @E[3],@C[7],@C[5]
380         eor     @E[2],@E[2],@C[2]
381         eor     @E[3],@E[3],@C[3]
382         str     @E[2],[sp,#$A[2][1]]            @ A[2][1] = C[1] ^ (~C[2] & C[3]);
383         bic     @E[0],@C[8],@C[6]
384         str     @E[3],[sp,#$A[2][1]+4]
385         bic     @E[1],@C[9],@C[7]
386         eor     @E[0],@E[0],@C[4]
387         eor     @E[1],@E[1],@C[5]
388         str     @E[0],[sp,#$A[2][2]]            @ A[2][2] = C[2] ^ (~C[3] & C[4]);
389         bic     @E[2],@C[0],@C[8]
390         str     @E[1],[sp,#$A[2][2]+4]
391         bic     @E[3],@C[1],@C[9]
392         eor     @E[2],@E[2],@C[6]
393         eor     @E[3],@E[3],@C[7]
394         str     @E[2],[sp,#$A[2][3]]            @ A[2][3] = C[3] ^ (~C[4] & C[0]);
395         bic     @E[0],@C[2],@C[0]
396         str     @E[3],[sp,#$A[2][3]+4]
397         bic     @E[1],@C[3],@C[1]
398         eor     @E[0],@E[0],@C[8]
399         eor     @E[1],@E[1],@C[9]
400         str     @E[0],[sp,#$A[2][4]]            @ A[2][4] = C[4] ^ (~C[0] & C[1]);
401          add    @C[2],sp,#$T[1][0]
402         str     @E[1],[sp,#$A[2][4]+4]
403
404         add     @E[3],sp,#$D[2]
405         ldr     @C[1],[sp,#$T[0][4]]
406         ldr     @C[0],[sp,#$T[0][4]+4]
407         ldmia   @C[2],{@C[2]-@C[5]}             @ T[1][0..1]
408         ldmia   @E[3],{@E[0]-@E[2],@E[3]}       @ D[2..3]
409         ror     @C[1],@C[1],#32-13              @ C[0] = ROL64(T[0][4],        rhotates[0][4]);
410         ldr     @C[6],[sp,#$A[3][2]]
411         ror     @C[0],@C[0],#32-14
412         ldr     @C[7],[sp,#$A[3][2]+4]
413         ror     @C[2],@C[2],#32-18              @ C[1] = ROL64(T[1][0],        rhotates[1][0]);
414         ldr     @C[8],[sp,#$A[4][3]]
415         ror     @C[3],@C[3],#32-18
416         ldr     @C[9],[sp,#$A[4][3]+4]
417         ror     @C[4],@C[4],#32-5               @ C[2] = ROL64(T[1][1],        rhotates[2][1]); /* originally A[2][1] */
418         eor     @E[0],@E[0],@C[6]
419         ror     @C[5],@C[5],#32-5
420         eor     @E[1],@E[1],@C[7]
421         ror     @C[7],@E[0],#32-7               @ C[3] = ROL64(A[3][2] ^ D[2], rhotates[3][2]);
422         eor     @C[8],@C[8],@E[2]
423         ror     @C[6],@E[1],#32-8
424         eor     @C[9],@C[9],@E[3]
425         ror     @C[8],@C[8],#32-28              @ C[4] = ROL64(A[4][3] ^ D[3], rhotates[4][3]);
426
427         bic     @E[0],@C[4],@C[2]
428          ror    @C[9],@C[9],#32-28
429         bic     @E[1],@C[5],@C[3]
430         eor     @E[0],@E[0],@C[0]
431         eor     @E[1],@E[1],@C[1]
432         str     @E[0],[sp,#$A[3][0]]            @ A[3][0] = C[0] ^ (~C[1] & C[2])
433         bic     @E[2],@C[6],@C[4]
434         str     @E[1],[sp,#$A[3][0]+4]
435         bic     @E[3],@C[7],@C[5]
436         eor     @E[2],@E[2],@C[2]
437         eor     @E[3],@E[3],@C[3]
438         str     @E[2],[sp,#$A[3][1]]            @ A[3][1] = C[1] ^ (~C[2] & C[3]);
439         bic     @E[0],@C[8],@C[6]
440         str     @E[3],[sp,#$A[3][1]+4]
441         bic     @E[1],@C[9],@C[7]
442         eor     @E[0],@E[0],@C[4]
443         eor     @E[1],@E[1],@C[5]
444         str     @E[0],[sp,#$A[3][2]]            @ A[3][2] = C[2] ^ (~C[3] & C[4]);
445         bic     @E[2],@C[0],@C[8]
446         str     @E[1],[sp,#$A[3][2]+4]
447         bic     @E[3],@C[1],@C[9]
448         eor     @E[2],@E[2],@C[6]
449         eor     @E[3],@E[3],@C[7]
450         str     @E[2],[sp,#$A[3][3]]            @ A[3][3] = C[3] ^ (~C[4] & C[0]);
451         bic     @E[0],@C[2],@C[0]
452         str     @E[3],[sp,#$A[3][3]+4]
453         bic     @E[1],@C[3],@C[1]
454         eor     @E[0],@E[0],@C[8]
455         eor     @E[1],@E[1],@C[9]
456         str     @E[0],[sp,#$A[3][4]]            @ A[3][4] = C[4] ^ (~C[0] & C[1]);
457          add    @E[3],sp,#$T[1][3]
458         str     @E[1],[sp,#$A[3][4]+4]
459
460         ldr     @C[0],[sp,#$T[0][2]]
461         ldr     @C[1],[sp,#$T[0][2]+4]
462         ldmia   @E[3],{@E[0]-@E[2],@E[3]}       @ T[1][3..4]
463         ldr     @C[7],[sp,#$T[0][0]]
464         ror     @C[0],@C[0],#32-31              @ C[0] = ROL64(T[0][2],        rhotates[0][2]);
465         ldr     @C[6],[sp,#$T[0][0]+4]
466         ror     @C[1],@C[1],#32-31
467         ldr     @C[8],[sp,#$A[4][1]]
468         ror     @C[3],@E[0],#32-27              @ C[1] = ROL64(T[1][3],        rhotates[1][3]);
469         ldr     @E[0],[sp,#$D[1]]
470         ror     @C[2],@E[1],#32-28
471         ldr     @C[9],[sp,#$A[4][1]+4]
472         ror     @C[5],@E[2],#32-19              @ C[2] = ROL64(T[1][4],        rhotates[2][4]); /* originally A[2][4] */
473         ldr     @E[1],[sp,#$D[1]+4]
474         ror     @C[4],@E[3],#32-20
475         eor     @C[8],@C[8],@E[0]
476         ror     @C[7],@C[7],#32-20              @ C[3] = ROL64(T[0][0],        rhotates[3][0]); /* originally A[3][0] */
477         eor     @C[9],@C[9],@E[1]
478         ror     @C[6],@C[6],#32-21
479
480         bic     @E[0],@C[4],@C[2]
481          ror    @C[8],@C[8],#32-1               @ C[4] = ROL64(A[4][1] ^ D[1], rhotates[4][1]);
482         bic     @E[1],@C[5],@C[3]
483          ror    @C[9],@C[9],#32-1
484         eor     @E[0],@E[0],@C[0]
485         eor     @E[1],@E[1],@C[1]
486         str     @E[0],[sp,#$A[4][0]]            @ A[4][0] = C[0] ^ (~C[1] & C[2])
487         bic     @E[2],@C[6],@C[4]
488         str     @E[1],[sp,#$A[4][0]+4]
489         bic     @E[3],@C[7],@C[5]
490         eor     @E[2],@E[2],@C[2]
491         eor     @E[3],@E[3],@C[3]
492         str     @E[2],[sp,#$A[4][1]]            @ A[4][1] = C[1] ^ (~C[2] & C[3]);
493         bic     @E[0],@C[8],@C[6]
494         str     @E[3],[sp,#$A[4][1]+4]
495         bic     @E[1],@C[9],@C[7]
496         eor     @E[0],@E[0],@C[4]
497         eor     @E[1],@E[1],@C[5]
498         str     @E[0],[sp,#$A[4][2]]            @ A[4][2] = C[2] ^ (~C[3] & C[4]);
499         bic     @E[2],@C[0],@C[8]
500         str     @E[1],[sp,#$A[4][2]+4]
501         bic     @E[3],@C[1],@C[9]
502         eor     @E[2],@E[2],@C[6]
503         eor     @E[3],@E[3],@C[7]
504         str     @E[2],[sp,#$A[4][3]]            @ A[4][3] = C[3] ^ (~C[4] & C[0]);
505         bic     @E[0],@C[2],@C[0]
506         str     @E[3],[sp,#$A[4][3]+4]
507         bic     @E[1],@C[3],@C[1]
508         eor     @E[2],@E[0],@C[8]
509          add    @E[0],sp,#$A[1][0]
510         eor     @E[3],@E[1],@C[9]
511          ldmia  sp,{@C[0]-@C[9]}                @ A[0][0..5]
512         str     @E[2],[sp,#$A[4][4]]            @ A[4][4] = C[4] ^ (~C[0] & C[1]);
513         str     @E[3],[sp,#$A[4][4]+4]
514
515         blo     .Lround
516
517         ldr     @E[1],[sp,#320]                 @ restore pointer to A
518         stmia   @E[1]!,{@C[0]-@C[9]}            @ copy A[5][5] from stack
519         ldmia   @E[0]!,{@C[0]-@C[9]}
520         stmia   @E[1]!,{@C[0]-@C[9]}
521         ldmia   @E[0]!,{@C[0]-@C[9]}
522         stmia   @E[1]!,{@C[0]-@C[9]}
523         ldmia   @E[0]!,{@C[0]-@C[9]}
524         stmia   @E[1]!,{@C[0]-@C[9]}
525         ldmia   @E[0],{@C[0]-@C[9]}
526         stmia   @E[1],{@C[0]-@C[9]}
527
528         add     sp,sp,#320+8
529         ldmia   sp!,{r4-r12,pc}
530 .size   KeccakF1600,.-KeccakF1600
531 ___
532 print $code;