1263320Sdim#! /usr/bin/env perl
2263320Sdim# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
3263320Sdim#
4263320Sdim# Licensed under the Apache License 2.0 (the "License").  You may not use
5263320Sdim# this file except in compliance with the License.  You can obtain a copy
6263320Sdim# in the file LICENSE in the source distribution or at
7263320Sdim# https://www.openssl.org/source/license.html
8263320Sdim
9263320Sdim
10263320Sdim# $output is the last argument if it looks like a file (it has an extension)
11263320Sdim# $flavour is the first argument if it doesn't look like a file
12263320Sdim$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
13263320Sdim$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
14263320Sdim
15263320Sdim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
16263320Sdim( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
17263320Sdim( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or
18263320Sdimdie "can't locate arm-xlate.pl";
19263320Sdim
20263320Sdimopen OUT,"| \"$^X\" $xlate $flavour \"$output\""
21263320Sdim    or die "can't call $xlate: $!";
22263320Sdim*STDOUT=*OUT;
23263320Sdim
24263320Sdim$code.=<<___;
25263320Sdim#include "arm_arch.h"
26263320Sdim
27263320Sdim#if defined(__thumb2__) && !defined(__APPLE__)
28263320Sdim.syntax	unified
29263320Sdim.thumb
30263320Sdim#else
31263320Sdim.code	32
32263320Sdim#undef	__thumb2__
33263320Sdim#endif
34263320Sdim
35263320Sdim.text
36263320Sdim
37263320Sdim.align	5
38263320Sdim.global	OPENSSL_atomic_add
39263320Sdim.type	OPENSSL_atomic_add,%function
40263320SdimOPENSSL_atomic_add:
41263320Sdim#if __ARM_ARCH__>=6
42263320Sdim.Ladd:	ldrex	r2,[r0]
43263320Sdim	add	r3,r2,r1
44263320Sdim	strex	r2,r3,[r0]
45263320Sdim	cmp	r2,#0
46263320Sdim	bne	.Ladd
47263320Sdim	mov	r0,r3
48263320Sdim	bx	lr
49263320Sdim#else
50263320Sdim	stmdb	sp!,{r4-r6,lr}
51263320Sdim	ldr	r2,.Lspinlock
52263320Sdim	adr	r3,.Lspinlock
53263320Sdim	mov	r4,r0
54263320Sdim	mov	r5,r1
55263320Sdim	add	r6,r3,r2	@ &spinlock
56263320Sdim	b	.+8
57263320Sdim.Lspin:	bl	sched_yield
58263320Sdim	mov	r0,#-1
59263320Sdim	swp	r0,r0,[r6]
60263320Sdim	cmp	r0,#0
61263320Sdim	bne	.Lspin
62263320Sdim
63263320Sdim	ldr	r2,[r4]
64263320Sdim	add	r2,r2,r5
65263320Sdim	str	r2,[r4]
66263320Sdim	str	r0,[r6]		@ release spinlock
67263320Sdim	ldmia	sp!,{r4-r6,lr}
68263320Sdim	tst	lr,#1
69263320Sdim	moveq	pc,lr
70263320Sdim	.word	0xe12fff1e	@ bx	lr
71263320Sdim#endif
72263320Sdim.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
73263320Sdim
74263320Sdim.global	OPENSSL_cleanse
75263320Sdim.type	OPENSSL_cleanse,%function
76263320SdimOPENSSL_cleanse:
77263320Sdim	eor	ip,ip,ip
78263320Sdim	cmp	r1,#7
79263320Sdim#ifdef	__thumb2__
80263320Sdim	itt	hs
81263320Sdim#endif
82263320Sdim	subhs	r1,r1,#4
83263320Sdim	bhs	.Lot
84263320Sdim	cmp	r1,#0
85263320Sdim	beq	.Lcleanse_done
86263320Sdim.Little:
87263320Sdim	strb	ip,[r0],#1
88263320Sdim	subs	r1,r1,#1
89263320Sdim	bhi	.Little
90263320Sdim	b	.Lcleanse_done
91263320Sdim
92263320Sdim.Lot:	tst	r0,#3
93263320Sdim	beq	.Laligned
94263320Sdim	strb	ip,[r0],#1
95263320Sdim	sub	r1,r1,#1
96263320Sdim	b	.Lot
97263320Sdim.Laligned:
98263320Sdim	str	ip,[r0],#4
99263320Sdim	subs	r1,r1,#4
100263320Sdim	bhs	.Laligned
101263320Sdim	adds	r1,r1,#4
102263320Sdim	bne	.Little
103263320Sdim.Lcleanse_done:
104263320Sdim#if __ARM_ARCH__>=5
105263320Sdim	bx	lr
106263320Sdim#else
107263320Sdim	tst	lr,#1
108263320Sdim	moveq	pc,lr
109263320Sdim	.word	0xe12fff1e	@ bx	lr
110263320Sdim#endif
111263320Sdim.size	OPENSSL_cleanse,.-OPENSSL_cleanse
112263320Sdim
113263320Sdim.global	CRYPTO_memcmp
114263320Sdim.type	CRYPTO_memcmp,%function
115263320Sdim.align	4
116263320SdimCRYPTO_memcmp:
117263320Sdim	eor	ip,ip,ip
118263320Sdim	cmp	r2,#0
119263320Sdim	beq	.Lno_data
120263320Sdim	stmdb	sp!,{r4,r5}
121263320Sdim
122263320Sdim.Loop_cmp:
123263320Sdim	ldrb	r4,[r0],#1
124263320Sdim	ldrb	r5,[r1],#1
125263320Sdim	eor	r4,r4,r5
126263320Sdim	orr	ip,ip,r4
127263320Sdim	subs	r2,r2,#1
128263320Sdim	bne	.Loop_cmp
129263320Sdim
130263320Sdim	ldmia	sp!,{r4,r5}
131263320Sdim.Lno_data:
132263320Sdim	rsb	r0,ip,#0
133263320Sdim	mov	r0,r0,lsr#31
134263320Sdim#if __ARM_ARCH__>=5
135263320Sdim	bx	lr
136263320Sdim#else
137263320Sdim	tst	lr,#1
138263320Sdim	moveq	pc,lr
139263320Sdim	.word	0xe12fff1e	@ bx	lr
140263320Sdim#endif
141263320Sdim.size	CRYPTO_memcmp,.-CRYPTO_memcmp
142263320Sdim
143263320Sdim#if __ARM_MAX_ARCH__>=7
144263320Sdim.arch	armv7-a
145263320Sdim.fpu	neon
146263320Sdim
147263320Sdim.align	5
148263320Sdim.global	_armv7_neon_probe
149263320Sdim.type	_armv7_neon_probe,%function
150263320Sdim_armv7_neon_probe:
151263320Sdim	vorr	q0,q0,q0
152263320Sdim	bx	lr
153263320Sdim.size	_armv7_neon_probe,.-_armv7_neon_probe
154263320Sdim
155263320Sdim.global	_armv7_tick
156263320Sdim.type	_armv7_tick,%function
157263320Sdim_armv7_tick:
158263320Sdim#ifdef	__APPLE__
159263320Sdim	mrrc	p15,0,r0,r1,c14		@ CNTPCT
160263320Sdim#else
161263320Sdim	mrrc	p15,1,r0,r1,c14		@ CNTVCT
162263320Sdim#endif
163263320Sdim	bx	lr
164263320Sdim.size	_armv7_tick,.-_armv7_tick
165263320Sdim
166263320Sdim.global	_armv8_aes_probe
167263320Sdim.type	_armv8_aes_probe,%function
168263320Sdim_armv8_aes_probe:
169263320Sdim#if defined(__thumb2__) && !defined(__APPLE__)
170	.byte	0xb0,0xff,0x00,0x03	@ aese.8	q0,q0
171#else
172	.byte	0x00,0x03,0xb0,0xf3	@ aese.8	q0,q0
173#endif
174	bx	lr
175.size	_armv8_aes_probe,.-_armv8_aes_probe
176
177.global	_armv8_sha1_probe
178.type	_armv8_sha1_probe,%function
179_armv8_sha1_probe:
180#if defined(__thumb2__) && !defined(__APPLE__)
181	.byte	0x00,0xef,0x40,0x0c	@ sha1c.32	q0,q0,q0
182#else
183	.byte	0x40,0x0c,0x00,0xf2	@ sha1c.32	q0,q0,q0
184#endif
185	bx	lr
186.size	_armv8_sha1_probe,.-_armv8_sha1_probe
187
188.global	_armv8_sha256_probe
189.type	_armv8_sha256_probe,%function
190_armv8_sha256_probe:
191#if defined(__thumb2__) && !defined(__APPLE__)
192	.byte	0x00,0xff,0x40,0x0c	@ sha256h.32	q0,q0,q0
193#else
194	.byte	0x40,0x0c,0x00,0xf3	@ sha256h.32	q0,q0,q0
195#endif
196	bx	lr
197.size	_armv8_sha256_probe,.-_armv8_sha256_probe
198.global	_armv8_pmull_probe
199.type	_armv8_pmull_probe,%function
200_armv8_pmull_probe:
201#if defined(__thumb2__) && !defined(__APPLE__)
202	.byte	0xa0,0xef,0x00,0x0e	@ vmull.p64	q0,d0,d0
203#else
204	.byte	0x00,0x0e,0xa0,0xf2	@ vmull.p64	q0,d0,d0
205#endif
206	bx	lr
207.size	_armv8_pmull_probe,.-_armv8_pmull_probe
208#endif
209
210.global	OPENSSL_wipe_cpu
211.type	OPENSSL_wipe_cpu,%function
212OPENSSL_wipe_cpu:
213#if __ARM_MAX_ARCH__>=7
214	ldr	r0,.LOPENSSL_armcap
215	adr	r1,.LOPENSSL_armcap
216	ldr	r0,[r1,r0]
217#ifdef	__APPLE__
218	ldr	r0,[r0]
219#endif
220#endif
221	eor	r2,r2,r2
222	eor	r3,r3,r3
223	eor	ip,ip,ip
224#if __ARM_MAX_ARCH__>=7
225	tst	r0,#1
226	beq	.Lwipe_done
227	veor	q0, q0, q0
228	veor	q1, q1, q1
229	veor	q2, q2, q2
230	veor	q3, q3, q3
231	veor	q8, q8, q8
232	veor	q9, q9, q9
233	veor	q10, q10, q10
234	veor	q11, q11, q11
235	veor	q12, q12, q12
236	veor	q13, q13, q13
237	veor	q14, q14, q14
238	veor	q15, q15, q15
239.Lwipe_done:
240#endif
241	mov	r0,sp
242#if __ARM_ARCH__>=5
243	bx	lr
244#else
245	tst	lr,#1
246	moveq	pc,lr
247	.word	0xe12fff1e	@ bx	lr
248#endif
249.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
250
251.global	OPENSSL_instrument_bus
252.type	OPENSSL_instrument_bus,%function
253OPENSSL_instrument_bus:
254	eor	r0,r0,r0
255#if __ARM_ARCH__>=5
256	bx	lr
257#else
258	tst	lr,#1
259	moveq	pc,lr
260	.word	0xe12fff1e	@ bx	lr
261#endif
262.size	OPENSSL_instrument_bus,.-OPENSSL_instrument_bus
263
264.global	OPENSSL_instrument_bus2
265.type	OPENSSL_instrument_bus2,%function
266OPENSSL_instrument_bus2:
267	eor	r0,r0,r0
268#if __ARM_ARCH__>=5
269	bx	lr
270#else
271	tst	lr,#1
272	moveq	pc,lr
273	.word	0xe12fff1e	@ bx	lr
274#endif
275.size	OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2
276
277.align	5
278#if __ARM_MAX_ARCH__>=7
279.LOPENSSL_armcap:
280.word	OPENSSL_armcap_P-.
281#endif
282#if __ARM_ARCH__>=6
283.align	5
284#else
285.Lspinlock:
286.word	atomic_add_spinlock-.Lspinlock
287.align	5
288
289.data
290.align	2
291atomic_add_spinlock:
292.word	0
293#endif
294
295.comm	OPENSSL_armcap_P,4,4
296.hidden	OPENSSL_armcap_P
297___
298
299print $code;
300close STDOUT or die "error closing STDOUT: $!";
301