Add an option not to use link(src, dest) && unlink(src) when that is unreliable
[git/spearce.git] / arm / sha1_arm.S
blob41e92636e0ff98ac620de75d66917999d55aca9e
1 /*
2  *  SHA transform optimized for ARM
3  *
4  *  Copyright:  (C) 2005 by Nicolas Pitre <nico@cam.org>
5  *  Created:    September 17, 2005
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  */
12         .text
13         .globl  arm_sha_transform
16  * void sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
17  *
18  * note: the "data" pointer may be unaligned.
19  */
21 arm_sha_transform:
23         stmfd   sp!, {r4 - r8, lr}
25         @ for (i = 0; i < 16; i++)
26         @         W[i] = ntohl(((uint32_t *)data)[i]);
28 #ifdef __ARMEB__
29         mov     r4, r0
30         mov     r0, r2
31         mov     r2, #64
32         bl      memcpy
33         mov     r2, r0
34         mov     r0, r4
35 #else
36         mov     r3, r2
37         mov     lr, #16
38 1:      ldrb    r4, [r1], #1
39         ldrb    r5, [r1], #1
40         ldrb    r6, [r1], #1
41         ldrb    r7, [r1], #1
42         subs    lr, lr, #1
43         orr     r5, r5, r4, lsl #8
44         orr     r6, r6, r5, lsl #8
45         orr     r7, r7, r6, lsl #8
46         str     r7, [r3], #4
47         bne     1b
48 #endif
50         @ for (i = 0; i < 64; i++)
51         @         W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
53         sub     r3, r2, #4
54         mov     lr, #64
55 2:      ldr     r4, [r3, #4]!
56         subs    lr, lr, #1
57         ldr     r5, [r3, #8]
58         ldr     r6, [r3, #32]
59         ldr     r7, [r3, #52]
60         eor     r4, r4, r5
61         eor     r4, r4, r6
62         eor     r4, r4, r7
63         mov     r4, r4, ror #31
64         str     r4, [r3, #64]
65         bne     2b
67         /*
68          * The SHA functions are:
69          *
70          * f1(B,C,D) = (D ^ (B & (C ^ D)))
71          * f2(B,C,D) = (B ^ C ^ D)
72          * f3(B,C,D) = ((B & C) | (D & (B | C)))
73          *
74          * Then the sub-blocks are processed as follows:
75          *
76          * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
77          * B' = A
78          * C' = ror(B, 2)
79          * D' = C
80          * E' = D
81          *
82          * We therefore unroll each loop 5 times to avoid register shuffling.
83          * Also the ror for C (and also D and E which are successivelyderived
84          * from it) is applied in place to cut on an additional mov insn for
85          * each round.
86          */
88         .macro  sha_f1, A, B, C, D, E
89         ldr     r3, [r2], #4
90         eor     ip, \C, \D
91         add     \E, r1, \E, ror #2
92         and     ip, \B, ip, ror #2
93         add     \E, \E, \A, ror #27
94         eor     ip, ip, \D, ror #2
95         add     \E, \E, r3
96         add     \E, \E, ip
97         .endm
99         .macro  sha_f2, A, B, C, D, E
100         ldr     r3, [r2], #4
101         add     \E, r1, \E, ror #2
102         eor     ip, \B, \C, ror #2
103         add     \E, \E, \A, ror #27
104         eor     ip, ip, \D, ror #2
105         add     \E, \E, r3
106         add     \E, \E, ip
107         .endm
109         .macro  sha_f3, A, B, C, D, E
110         ldr     r3, [r2], #4
111         add     \E, r1, \E, ror #2
112         orr     ip, \B, \C, ror #2
113         add     \E, \E, \A, ror #27
114         and     ip, ip, \D, ror #2
115         add     \E, \E, r3
116         and     r3, \B, \C, ror #2
117         orr     ip, ip, r3
118         add     \E, \E, ip
119         .endm
121         ldmia   r0, {r4 - r8}
123         mov     lr, #4
124         ldr     r1, .L_sha_K + 0
126         /* adjust initial values */
127         mov     r6, r6, ror #30
128         mov     r7, r7, ror #30
129         mov     r8, r8, ror #30
131 3:      subs    lr, lr, #1
132         sha_f1  r4, r5, r6, r7, r8
133         sha_f1  r8, r4, r5, r6, r7
134         sha_f1  r7, r8, r4, r5, r6
135         sha_f1  r6, r7, r8, r4, r5
136         sha_f1  r5, r6, r7, r8, r4
137         bne     3b
139         ldr     r1, .L_sha_K + 4
140         mov     lr, #4
142 4:      subs    lr, lr, #1
143         sha_f2  r4, r5, r6, r7, r8
144         sha_f2  r8, r4, r5, r6, r7
145         sha_f2  r7, r8, r4, r5, r6
146         sha_f2  r6, r7, r8, r4, r5
147         sha_f2  r5, r6, r7, r8, r4
148         bne     4b
150         ldr     r1, .L_sha_K + 8
151         mov     lr, #4
153 5:      subs    lr, lr, #1
154         sha_f3  r4, r5, r6, r7, r8
155         sha_f3  r8, r4, r5, r6, r7
156         sha_f3  r7, r8, r4, r5, r6
157         sha_f3  r6, r7, r8, r4, r5
158         sha_f3  r5, r6, r7, r8, r4
159         bne     5b
161         ldr     r1, .L_sha_K + 12
162         mov     lr, #4
164 6:      subs    lr, lr, #1
165         sha_f2  r4, r5, r6, r7, r8
166         sha_f2  r8, r4, r5, r6, r7
167         sha_f2  r7, r8, r4, r5, r6
168         sha_f2  r6, r7, r8, r4, r5
169         sha_f2  r5, r6, r7, r8, r4
170         bne     6b
172         ldmia   r0, {r1, r2, r3, ip, lr}
173         add     r4, r1, r4
174         add     r5, r2, r5
175         add     r6, r3, r6, ror #2
176         add     r7, ip, r7, ror #2
177         add     r8, lr, r8, ror #2
178         stmia   r0, {r4 - r8}
180         ldmfd   sp!, {r4 - r8, pc}
182 .L_sha_K:
183         .word   0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6