1#! /usr/bin/env perl
2# Copyright 2007-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}ppc-xlate.pl" and -f $xlate ) or
17( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or
18die "can't locate ppc-xlate.pl";
19
20open STDOUT,"| $^X $xlate $flavour \"$output\""
21    or die "can't call $xlate: $!";
22
23if ($flavour=~/64/) {
24    $CMPLI="cmpldi";
25    $SHRLI="srdi";
26    $SIGNX="extsw";
27} else {
28    $CMPLI="cmplwi";
29    $SHRLI="srwi";
30    $SIGNX="mr";
31}
32
33$code=<<___;
34.machine	"any"
35.text
36
37.globl	.OPENSSL_fpu_probe
38.align	4
39.OPENSSL_fpu_probe:
40	fmr	f0,f0
41	blr
42	.long	0
43	.byte	0,12,0x14,0,0,0,0,0
44.size	.OPENSSL_fpu_probe,.-.OPENSSL_fpu_probe
45.globl	.OPENSSL_ppc64_probe
46.align	4
47.OPENSSL_ppc64_probe:
48	fcfid	f1,f1
49	extrdi	r0,r0,32,0
50	blr
51	.long	0
52	.byte	0,12,0x14,0,0,0,0,0
53.size	.OPENSSL_ppc64_probe,.-.OPENSSL_ppc64_probe
54
55.globl	.OPENSSL_altivec_probe
56.align	4
57.OPENSSL_altivec_probe:
58	.long	0x10000484	# vor	v0,v0,v0
59	blr
60	.long	0
61	.byte	0,12,0x14,0,0,0,0,0
62.size	.OPENSSL_altivec_probe,.-..OPENSSL_altivec_probe
63
64.globl	.OPENSSL_crypto207_probe
65.align	4
66.OPENSSL_crypto207_probe:
67	lvx_u	v0,0,r1
68	vcipher	v0,v0,v0
69	blr
70	.long	0
71	.byte	0,12,0x14,0,0,0,0,0
72.size	.OPENSSL_crypto207_probe,.-.OPENSSL_crypto207_probe
73
74.globl	.OPENSSL_madd300_probe
75.align	4
76.OPENSSL_madd300_probe:
77	xor	r0,r0,r0
78	maddld	r3,r0,r0,r0
79	maddhdu	r3,r0,r0,r0
80	blr
81	.long	0
82	.byte	0,12,0x14,0,0,0,0,0
83
84.globl	.OPENSSL_brd31_probe
85.align	4
86.OPENSSL_brd31_probe:
87	xor	r0,r0,r0
88	brd	r3,r0
89	blr
90	.long	0
91	.byte	0,12,0x14,0,0,0,0,0
92.size	.OPENSSL_brd31_probe,.-.OPENSSL_brd31_probe
93
94.globl	.OPENSSL_atomic_add
95.align	4
96.OPENSSL_atomic_add:
97Ladd:	lwarx	r5,0,r3
98	add	r0,r4,r5
99	stwcx.	r0,0,r3
100	bne-	Ladd
101	$SIGNX	r3,r0
102	blr
103	.long	0
104	.byte	0,12,0x14,0,0,0,2,0
105	.long	0
106.size	.OPENSSL_atomic_add,.-.OPENSSL_atomic_add
107
108.globl	.OPENSSL_rdtsc_mftb
109.align	4
110.OPENSSL_rdtsc_mftb:
111	mftb	r3
112	blr
113	.long	0
114	.byte	0,12,0x14,0,0,0,0,0
115.size	.OPENSSL_rdtsc_mftb,.-.OPENSSL_rdtsc_mftb
116
117.globl	.OPENSSL_rdtsc_mfspr268
118.align	4
119.OPENSSL_rdtsc_mfspr268:
120	mfspr	r3,268
121	blr
122	.long	0
123	.byte	0,12,0x14,0,0,0,0,0
124.size	.OPENSSL_rdtsc_mfspr268,.-.OPENSSL_rdtsc_mfspr268
125
126.globl	.OPENSSL_cleanse
127.align	4
128.OPENSSL_cleanse:
129	$CMPLI	r4,7
130	li	r0,0
131	bge	Lot
132	$CMPLI	r4,0
133	beqlr-
134Little:	mtctr	r4
135	stb	r0,0(r3)
136	addi	r3,r3,1
137	bdnz	\$-8
138	blr
139Lot:	andi.	r5,r3,3
140	beq	Laligned
141	stb	r0,0(r3)
142	subi	r4,r4,1
143	addi	r3,r3,1
144	b	Lot
145Laligned:
146	$SHRLI	r5,r4,2
147	mtctr	r5
148	stw	r0,0(r3)
149	addi	r3,r3,4
150	bdnz	\$-8
151	andi.	r4,r4,3
152	bne	Little
153	blr
154	.long	0
155	.byte	0,12,0x14,0,0,0,2,0
156	.long	0
157.size	.OPENSSL_cleanse,.-.OPENSSL_cleanse
158
159globl	.CRYPTO_memcmp
160.align	4
161.CRYPTO_memcmp:
162	$CMPLI	r5,0
163	li	r0,0
164	beq	Lno_data
165	mtctr	r5
166Loop_cmp:
167	lbz	r6,0(r3)
168	addi	r3,r3,1
169	lbz	r7,0(r4)
170	addi	r4,r4,1
171	xor	r6,r6,r7
172	or	r0,r0,r6
173	bdnz	Loop_cmp
174
175Lno_data:
176	li	r3,0
177	sub	r3,r3,r0
178	extrwi	r3,r3,1,0
179	blr
180	.long	0
181	.byte	0,12,0x14,0,0,0,3,0
182	.long	0
183.size	.CRYPTO_memcmp,.-.CRYPTO_memcmp
184___
185{
186my ($out,$cnt,$max)=("r3","r4","r5");
187my ($tick,$lasttick)=("r6","r7");
188my ($diff,$lastdiff)=("r8","r9");
189
190$code.=<<___;
191.globl	.OPENSSL_instrument_bus_mftb
192.align	4
193.OPENSSL_instrument_bus_mftb:
194	mtctr	$cnt
195
196	mftb	$lasttick		# collect 1st tick
197	li	$diff,0
198
199	dcbf	0,$out			# flush cache line
200	lwarx	$tick,0,$out		# load and lock
201	add	$tick,$tick,$diff
202	stwcx.	$tick,0,$out
203	stwx	$tick,0,$out
204
205Loop:	mftb	$tick
206	sub	$diff,$tick,$lasttick
207	mr	$lasttick,$tick
208	dcbf	0,$out			# flush cache line
209	lwarx	$tick,0,$out		# load and lock
210	add	$tick,$tick,$diff
211	stwcx.	$tick,0,$out
212	stwx	$tick,0,$out
213	addi	$out,$out,4		# ++$out
214	bdnz	Loop
215
216	mr	r3,$cnt
217	blr
218	.long	0
219	.byte	0,12,0x14,0,0,0,2,0
220	.long	0
221.size	.OPENSSL_instrument_bus_mftb,.-.OPENSSL_instrument_bus_mftb
222
223.globl	.OPENSSL_instrument_bus2_mftb
224.align	4
225.OPENSSL_instrument_bus2_mftb:
226	mr	r0,$cnt
227	slwi	$cnt,$cnt,2
228
229	mftb	$lasttick		# collect 1st tick
230	li	$diff,0
231
232	dcbf	0,$out			# flush cache line
233	lwarx	$tick,0,$out		# load and lock
234	add	$tick,$tick,$diff
235	stwcx.	$tick,0,$out
236	stwx	$tick,0,$out
237
238	mftb	$tick			# collect 1st diff
239	sub	$diff,$tick,$lasttick
240	mr	$lasttick,$tick
241	mr	$lastdiff,$diff
242Loop2:
243	dcbf	0,$out			# flush cache line
244	lwarx	$tick,0,$out		# load and lock
245	add	$tick,$tick,$diff
246	stwcx.	$tick,0,$out
247	stwx	$tick,0,$out
248
249	addic.	$max,$max,-1
250	beq	Ldone2
251
252	mftb	$tick
253	sub	$diff,$tick,$lasttick
254	mr	$lasttick,$tick
255	cmplw	7,$diff,$lastdiff
256	mr	$lastdiff,$diff
257
258	mfcr	$tick			# pull cr
259	not	$tick,$tick		# flip bits
260	rlwinm	$tick,$tick,1,29,29	# isolate flipped eq bit and scale
261
262	sub.	$cnt,$cnt,$tick		# conditional --$cnt
263	add	$out,$out,$tick		# conditional ++$out
264	bne	Loop2
265
266Ldone2:
267	srwi	$cnt,$cnt,2
268	sub	r3,r0,$cnt
269	blr
270	.long	0
271	.byte	0,12,0x14,0,0,0,3,0
272	.long	0
273.size	.OPENSSL_instrument_bus2_mftb,.-.OPENSSL_instrument_bus2_mftb
274
275.globl	.OPENSSL_instrument_bus_mfspr268
276.align	4
277.OPENSSL_instrument_bus_mfspr268:
278	mtctr	$cnt
279
280	mfspr	$lasttick,268		# collect 1st tick
281	li	$diff,0
282
283	dcbf	0,$out			# flush cache line
284	lwarx	$tick,0,$out		# load and lock
285	add	$tick,$tick,$diff
286	stwcx.	$tick,0,$out
287	stwx	$tick,0,$out
288
289Loop3:	mfspr	$tick,268
290	sub	$diff,$tick,$lasttick
291	mr	$lasttick,$tick
292	dcbf	0,$out			# flush cache line
293	lwarx	$tick,0,$out		# load and lock
294	add	$tick,$tick,$diff
295	stwcx.	$tick,0,$out
296	stwx	$tick,0,$out
297	addi	$out,$out,4		# ++$out
298	bdnz	Loop3
299
300	mr	r3,$cnt
301	blr
302	.long	0
303	.byte	0,12,0x14,0,0,0,2,0
304	.long	0
305.size	.OPENSSL_instrument_bus_mfspr268,.-.OPENSSL_instrument_bus_mfspr268
306
307.globl	.OPENSSL_instrument_bus2_mfspr268
308.align	4
309.OPENSSL_instrument_bus2_mfspr268:
310	mr	r0,$cnt
311	slwi	$cnt,$cnt,2
312
313	mfspr	$lasttick,268		# collect 1st tick
314	li	$diff,0
315
316	dcbf	0,$out			# flush cache line
317	lwarx	$tick,0,$out		# load and lock
318	add	$tick,$tick,$diff
319	stwcx.	$tick,0,$out
320	stwx	$tick,0,$out
321
322	mfspr	$tick,268		# collect 1st diff
323	sub	$diff,$tick,$lasttick
324	mr	$lasttick,$tick
325	mr	$lastdiff,$diff
326Loop4:
327	dcbf	0,$out			# flush cache line
328	lwarx	$tick,0,$out		# load and lock
329	add	$tick,$tick,$diff
330	stwcx.	$tick,0,$out
331	stwx	$tick,0,$out
332
333	addic.	$max,$max,-1
334	beq	Ldone4
335
336	mfspr	$tick,268
337	sub	$diff,$tick,$lasttick
338	mr	$lasttick,$tick
339	cmplw	7,$diff,$lastdiff
340	mr	$lastdiff,$diff
341
342	mfcr	$tick			# pull cr
343	not	$tick,$tick		# flip bits
344	rlwinm	$tick,$tick,1,29,29	# isolate flipped eq bit and scale
345
346	sub.	$cnt,$cnt,$tick		# conditional --$cnt
347	add	$out,$out,$tick		# conditional ++$out
348	bne	Loop4
349
350Ldone4:
351	srwi	$cnt,$cnt,2
352	sub	r3,r0,$cnt
353	blr
354	.long	0
355	.byte	0,12,0x14,0,0,0,3,0
356	.long	0
357.size	.OPENSSL_instrument_bus2_mfspr268,.-.OPENSSL_instrument_bus2_mfspr268
358___
359}
360
361$code =~ s/\`([^\`]*)\`/eval $1/gem;
362print $code;
363close STDOUT or die "error closing STDOUT: $!";
364