Add CFI unwind assembly directives for 64-bit ARM assembly
[libgcrypt.git] / cipher / sha256-armv8-aarch64-ce.S
1 /* sha256-armv8-aarch64-ce.S - ARM/CE accelerated SHA-256 transform function
2  * Copyright (C) 2016 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "asm-common-aarch64.h"
21
22 #if defined(__AARCH64EL__) && \
23     defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) && \
24     defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO) && defined(USE_SHA256)
25
26 .cpu generic+simd+crypto
27
28 .text
29
30
31 #define GET_DATA_POINTER(reg, name) \
32                 adrp    reg, :got:name ; \
33                 ldr     reg, [reg, #:got_lo12:name] ;
34
35
36 /* Constants */
37
38 .align 4
39 gcry_sha256_aarch64_ce_K:
40 .LK:
41   .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
42   .long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
43   .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
44   .long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
45   .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
46   .long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
47   .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
48   .long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
49   .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
50   .long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
51   .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
52   .long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
53   .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
54   .long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
55   .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
56   .long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
57
58
59 /* Register macros */
60
61 #define vH0123 v0
62 #define vH4567 v1
63
64 #define vABCD0 v2
65 #define qABCD0 q2
66 #define vABCD1 v3
67 #define qABCD1 q3
68 #define vEFGH  v4
69 #define qEFGH  q4
70
71 #define vT0 v5
72 #define vT1 v6
73
74 #define vW0 v16
75 #define vW1 v17
76 #define vW2 v18
77 #define vW3 v19
78
79 #define vK0 v20
80 #define vK1 v21
81 #define vK2 v22
82 #define vK3 v23
83
84
85 /* Round macros */
86
87 #define _(...) /*_*/
88
89 #define do_loadk(nk0, nk1) ld1 {nk0.16b-nk1.16b},[x3],#32;
90 #define do_add(a, b) add a.4s, a.4s, b.4s;
91 #define do_sha256su0(w0, w1) sha256su0 w0.4s, w1.4s;
92 #define do_sha256su1(w0, w2, w3) sha256su1 w0.4s, w2.4s, w3.4s;
93
94 #define do_rounds(k, nk0, nk1, w0, w1, w2, w3, loadk_fn, add_fn, su0_fn, su1_fn) \
95         loadk_fn(   v##nk0, v##nk1     ); \
96         su0_fn(     v##w0, v##w1       ); \
97         mov         vABCD1.16b, vABCD0.16b; \
98         sha256h     qABCD0, qEFGH, v##k.4s; \
99         sha256h2    qEFGH, qABCD1, v##k.4s; \
100         add_fn(     v##nk0, v##w2      ); \
101         su1_fn(     v##w0, v##w2, v##w3   );
102
103
104 /* Other functional macros */
105
106 #define CLEAR_REG(reg) eor reg.16b, reg.16b, reg.16b;
107
108
109 /*
110  * unsigned int
111  * _gcry_sha256_transform_armv8_ce (u32 state[8], const void *input_data,
112  *                                  size_t num_blks)
113  */
114 .align 3
115 .globl _gcry_sha256_transform_armv8_ce
116 ELF(.type  _gcry_sha256_transform_armv8_ce,%function;)
117 _gcry_sha256_transform_armv8_ce:
118   /* input:
119    *    r0: ctx, CTX
120    *    r1: data (64*nblks bytes)
121    *    r2: nblks
122    */
123   CFI_STARTPROC();
124
125   cbz x2, .Ldo_nothing;
126
127   GET_DATA_POINTER(x3, .LK);
128   mov x4, x3
129
130   ld1 {vH0123.4s-vH4567.4s}, [x0]  /* load state */
131
132   ld1 {vW0.16b-vW1.16b}, [x1], #32
133   do_loadk(vK0, vK1)
134   ld1 {vW2.16b-vW3.16b}, [x1], #32
135   mov vABCD0.16b, vH0123.16b
136   mov vEFGH.16b, vH4567.16b
137
138   rev32 vW0.16b, vW0.16b
139   rev32 vW1.16b, vW1.16b
140   rev32 vW2.16b, vW2.16b
141   do_add(vK0, vW0)
142   rev32 vW3.16b, vW3.16b
143   do_add(vK1, vW1)
144
145 .Loop:
146   do_rounds(K0, K2, K3, W0, W1, W2, W3, do_loadk, do_add, do_sha256su0, do_sha256su1)
147   sub x2,x2,#1
148   do_rounds(K1, K3, _ , W1, W2, W3, W0, _       , do_add, do_sha256su0, do_sha256su1)
149   do_rounds(K2, K0, K1, W2, W3, W0, W1, do_loadk, do_add, do_sha256su0, do_sha256su1)
150   do_rounds(K3, K1, _ , W3, W0, W1, W2, _       , do_add, do_sha256su0, do_sha256su1)
151
152   do_rounds(K0, K2, K3, W0, W1, W2, W3, do_loadk, do_add, do_sha256su0, do_sha256su1)
153   do_rounds(K1, K3, _ , W1, W2, W3, W0, _       , do_add, do_sha256su0, do_sha256su1)
154   do_rounds(K2, K0, K1, W2, W3, W0, W1, do_loadk, do_add, do_sha256su0, do_sha256su1)
155   do_rounds(K3, K1, _ , W3, W0, W1, W2, _       , do_add, do_sha256su0, do_sha256su1)
156
157   do_rounds(K0, K2, K3, W0, W1, W2, W3, do_loadk, do_add, do_sha256su0, do_sha256su1)
158   do_rounds(K1, K3, _ , W1, W2, W3, W0, _       , do_add, do_sha256su0, do_sha256su1)
159   do_rounds(K2, K0, K1, W2, W3, W0, W1, do_loadk, do_add, do_sha256su0, do_sha256su1)
160   do_rounds(K3, K1, _ , W3, W0, W1, W2, _       , do_add, do_sha256su0, do_sha256su1)
161
162   cbz x2, .Lend
163
164   do_rounds(K0, K2, K3, W0, _  , W2, W3, do_loadk, do_add, _, _)
165   ld1 {vW0.16b}, [x1], #16
166   mov x3, x4
167   do_rounds(K1, K3, _ , W1, _  , W3, _  , _       , do_add, _, _)
168   ld1 {vW1.16b}, [x1], #16
169   rev32 vW0.16b, vW0.16b
170   do_rounds(K2, K0, K1, W2, _  , W0, _  , do_loadk, do_add, _, _)
171   rev32 vW1.16b, vW1.16b
172   ld1 {vW2.16b}, [x1], #16
173   do_rounds(K3, K1, _ , W3, _  , W1, _  , _       , do_add, _, _)
174   ld1 {vW3.16b}, [x1], #16
175
176   do_add(vH0123, vABCD0)
177   do_add(vH4567, vEFGH)
178
179   rev32 vW2.16b, vW2.16b
180   mov vABCD0.16b, vH0123.16b
181   rev32 vW3.16b, vW3.16b
182   mov vEFGH.16b, vH4567.16b
183
184   b .Loop
185
186 .Lend:
187
188   do_rounds(K0, K2, K3, W0, _  , W2, W3, do_loadk, do_add, _, _)
189   do_rounds(K1, K3, _ , W1, _  , W3, _  , _       , do_add, _, _)
190   do_rounds(K2, _ , _ , W2, _  , _  , _  , _       , _, _, _)
191   do_rounds(K3, _ , _ , W3, _  , _  , _  , _       , _, _, _)
192
193   CLEAR_REG(vW0)
194   CLEAR_REG(vW1)
195   CLEAR_REG(vW2)
196   CLEAR_REG(vW3)
197   CLEAR_REG(vK0)
198   CLEAR_REG(vK1)
199   CLEAR_REG(vK2)
200   CLEAR_REG(vK3)
201
202   do_add(vH0123, vABCD0)
203   do_add(vH4567, vEFGH)
204
205   CLEAR_REG(vABCD0)
206   CLEAR_REG(vABCD1)
207   CLEAR_REG(vEFGH)
208
209   st1 {vH0123.4s-vH4567.4s}, [x0] /* store state */
210
211   CLEAR_REG(vH0123)
212   CLEAR_REG(vH4567)
213
214 .Ldo_nothing:
215   mov x0, #0
216   ret
217   CFI_ENDPROC();
218 ELF(.size _gcry_sha256_transform_armv8_ce,.-_gcry_sha256_transform_armv8_ce;)
219
220 #endif