xref: /openssl/crypto/arm64cpuid.pl (revision fecb3aae)
1#! /usr/bin/env perl
2# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the Apache License 2.0 (the "License").  You may not use
5# this file except in compliance with the License.  You can obtain a copy
6# in the file LICENSE in the source distribution or at
7# https://www.openssl.org/source/license.html
8
9
10# $output is the last argument if it looks like a file (it has an extension)
11# $flavour is the first argument if it doesn't look like a file
12$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
13$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
14
15$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
16( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
17( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or
18die "can't locate arm-xlate.pl";
19
20open OUT,"| \"$^X\" $xlate $flavour \"$output\""
21    or die "can't call $xlate: $!";
22*STDOUT=*OUT;
23
24$code.=<<___;
25#include "arm_arch.h"
26
27.text
28.arch	armv8-a+crypto
29
30.align	5
31.globl	_armv7_neon_probe
32.type	_armv7_neon_probe,%function
33_armv7_neon_probe:
34	AARCH64_VALID_CALL_TARGET
35	orr	v15.16b, v15.16b, v15.16b
36	ret
37.size	_armv7_neon_probe,.-_armv7_neon_probe
38
39.globl	_armv7_tick
40.type	_armv7_tick,%function
41_armv7_tick:
42	AARCH64_VALID_CALL_TARGET
43#ifdef	__APPLE__
44	mrs	x0, CNTPCT_EL0
45#else
46	mrs	x0, CNTVCT_EL0
47#endif
48	ret
49.size	_armv7_tick,.-_armv7_tick
50
51.globl	_armv8_aes_probe
52.type	_armv8_aes_probe,%function
53_armv8_aes_probe:
54	AARCH64_VALID_CALL_TARGET
55	aese	v0.16b, v0.16b
56	ret
57.size	_armv8_aes_probe,.-_armv8_aes_probe
58
59.globl	_armv8_sha1_probe
60.type	_armv8_sha1_probe,%function
61_armv8_sha1_probe:
62	AARCH64_VALID_CALL_TARGET
63	sha1h	s0, s0
64	ret
65.size	_armv8_sha1_probe,.-_armv8_sha1_probe
66
67.globl	_armv8_sha256_probe
68.type	_armv8_sha256_probe,%function
69_armv8_sha256_probe:
70	AARCH64_VALID_CALL_TARGET
71	sha256su0	v0.4s, v0.4s
72	ret
73.size	_armv8_sha256_probe,.-_armv8_sha256_probe
74
75.globl	_armv8_pmull_probe
76.type	_armv8_pmull_probe,%function
77_armv8_pmull_probe:
78	AARCH64_VALID_CALL_TARGET
79	pmull	v0.1q, v0.1d, v0.1d
80	ret
81.size	_armv8_pmull_probe,.-_armv8_pmull_probe
82
83.globl	_armv8_sm4_probe
84.type	_armv8_sm4_probe,%function
85_armv8_sm4_probe:
86	AARCH64_VALID_CALL_TARGET
87	.inst	0xcec08400	// sm4e	v0.4s, v0.4s
88	ret
89.size	_armv8_sm4_probe,.-_armv8_sm4_probe
90
91.globl	_armv8_sha512_probe
92.type	_armv8_sha512_probe,%function
93_armv8_sha512_probe:
94	AARCH64_VALID_CALL_TARGET
95	.inst	0xcec08000	// sha512su0	v0.2d,v0.2d
96	ret
97.size	_armv8_sha512_probe,.-_armv8_sha512_probe
98
99.globl	_armv8_eor3_probe
100.type	_armv8_eor3_probe,%function
101_armv8_eor3_probe:
102	AARCH64_VALID_CALL_TARGET
103	.inst	0xce010800	// eor3	v0.16b, v0.16b, v1.16b, v2.16b
104	ret
105.size	_armv8_eor3_probe,.-_armv8_eor3_probe
106
107.globl	_armv8_sve_probe
108.type	_armv8_sve_probe,%function
109_armv8_sve_probe:
110	AARCH64_VALID_CALL_TARGET
111	.inst	0x04a03000	// eor z0.d,z0.d,z0.d
112	ret
113.size	_armv8_sve_probe,.-_armv8_sve_probe
114
115.globl	_armv8_sve2_probe
116.type	_armv8_sve2_probe,%function
117_armv8_sve2_probe:
118	AARCH64_VALID_CALL_TARGET
119	.inst	0x04e03400	// xar z0.d,z0.d,z0.d
120	ret
121.size	_armv8_sve2_probe,.-_armv8_sve2_probe
122
123.globl	_armv8_cpuid_probe
124.type	_armv8_cpuid_probe,%function
125_armv8_cpuid_probe:
126	AARCH64_VALID_CALL_TARGET
127	mrs	x0, midr_el1
128	ret
129.size	_armv8_cpuid_probe,.-_armv8_cpuid_probe
130
131.globl	_armv8_sm3_probe
132.type	_armv8_sm3_probe,%function
133_armv8_sm3_probe:
134	AARCH64_VALID_CALL_TARGET
135	.inst	0xce63c004	// sm3partw1 v4.4s, v0.4s, v3.4s
136	ret
137.size	_armv8_sm3_probe,.-_armv8_sm3_probe
138
139.globl	OPENSSL_cleanse
140.type	OPENSSL_cleanse,%function
141.align	5
142OPENSSL_cleanse:
143	AARCH64_VALID_CALL_TARGET
144	cbz	x1,.Lret	// len==0?
145	cmp	x1,#15
146	b.hi	.Lot		// len>15
147	nop
148.Little:
149	strb	wzr,[x0],#1	// store byte-by-byte
150	subs	x1,x1,#1
151	b.ne	.Little
152.Lret:	ret
153
154.align	4
155.Lot:	tst	x0,#7
156	b.eq	.Laligned	// inp is aligned
157	strb	wzr,[x0],#1	// store byte-by-byte
158	sub	x1,x1,#1
159	b	.Lot
160
161.align	4
162.Laligned:
163	str	xzr,[x0],#8	// store word-by-word
164	sub	x1,x1,#8
165	tst	x1,#-8
166	b.ne	.Laligned	// len>=8
167	cbnz	x1,.Little	// len!=0?
168	ret
169.size	OPENSSL_cleanse,.-OPENSSL_cleanse
170
171.globl	CRYPTO_memcmp
172.type	CRYPTO_memcmp,%function
173.align	4
174CRYPTO_memcmp:
175	AARCH64_VALID_CALL_TARGET
176	eor	w3,w3,w3
177	cbz	x2,.Lno_data	// len==0?
178	cmp	x2,#16
179	b.ne	.Loop_cmp
180	ldp	x8,x9,[x0]
181	ldp	x10,x11,[x1]
182	eor	x8,x8,x10
183	eor	x9,x9,x11
184	orr	x8,x8,x9
185	mov	x0,#1
186	cmp	x8,#0
187	csel	x0,xzr,x0,eq
188	ret
189
190.align	4
191.Loop_cmp:
192	ldrb	w4,[x0],#1
193	ldrb	w5,[x1],#1
194	eor	w4,w4,w5
195	orr	w3,w3,w4
196	subs	x2,x2,#1
197	b.ne	.Loop_cmp
198
199.Lno_data:
200	neg	w0,w3
201	lsr	w0,w0,#31
202	ret
203.size	CRYPTO_memcmp,.-CRYPTO_memcmp
204
205.globl	_armv8_rng_probe
206.type	_armv8_rng_probe,%function
207_armv8_rng_probe:
208	AARCH64_VALID_CALL_TARGET
209	mrs	x0, s3_3_c2_c4_0	// rndr
210	mrs	x0, s3_3_c2_c4_1	// rndrrs
211	ret
212.size	_armv8_rng_probe,.-_armv8_rng_probe
213___
214
215sub gen_random {
216my $rdop = shift;
217my $rand_reg = $rdop eq "rndr" ? "s3_3_c2_c4_0" : "s3_3_c2_c4_1";
218
219return <<___;
220// Fill buffer with Randomly Generated Bytes
221// inputs:  char * in x0 - Pointer to buffer
222//          size_t in x1 - Number of bytes to write to buffer
223// outputs: size_t in x0 - Number of bytes successfully written to buffer
224.globl	OPENSSL_${rdop}_asm
225.type	OPENSSL_${rdop}_asm,%function
226.align	4
227OPENSSL_${rdop}_asm:
228	AARCH64_VALID_CALL_TARGET
229	mov	x2,xzr
230	mov	x3,xzr
231
232.align	4
233.Loop_${rdop}:
234	cmp	x1,#0
235	b.eq	.${rdop}_done
236	mov	x3,xzr
237	mrs	x3,$rand_reg
238	b.eq	.${rdop}_done
239
240	cmp	x1,#8
241	b.lt	.Loop_single_byte_${rdop}
242
243	str	x3,[x0]
244	add	x0,x0,#8
245	add	x2,x2,#8
246	subs	x1,x1,#8
247	b.ge	.Loop_${rdop}
248
249.align	4
250.Loop_single_byte_${rdop}:
251	strb	w3,[x0]
252	lsr	x3,x3,#8
253	add	x2,x2,#1
254	add	x0,x0,#1
255	subs	x1,x1,#1
256	b.gt	.Loop_single_byte_${rdop}
257
258.align	4
259.${rdop}_done:
260	mov	x0,x2
261	ret
262.size	OPENSSL_${rdop}_asm,.-OPENSSL_${rdop}_asm
263___
264}
265
266$code .= gen_random("rndr");
267$code .= gen_random("rndrrs");
268
269print $code;
270close STDOUT or die "error closing STDOUT: $!";
271