|  | #! /usr/bin/env perl | 
|  | # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. | 
|  | # | 
|  | # Licensed under the OpenSSL license (the "License").  You may not use | 
|  | # this file except in compliance with the License.  You can obtain a copy | 
|  | # in the file LICENSE in the source distribution or at | 
|  | # https://www.openssl.org/source/license.html | 
|  |  | 
|  |  | 
|  | $flavour = shift; | 
|  | $output = shift; | 
|  | open STDOUT,">$output"; | 
|  |  | 
|  | if ($flavour =~ /64/) { | 
|  | $LEVEL		="2.0W"; | 
|  | $SIZE_T		=8; | 
|  | $ST		="std"; | 
|  | } else { | 
|  | $LEVEL		="1.1"; | 
|  | $SIZE_T		=4; | 
|  | $ST		="stw"; | 
|  | } | 
|  |  | 
|  | $rp="%r2"; | 
|  | $sp="%r30"; | 
|  | $rv="%r28"; | 
|  |  | 
|  | $code=<<___; | 
|  | .LEVEL	$LEVEL | 
|  | .SPACE	\$TEXT\$ | 
|  | .SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY | 
|  |  | 
|  | .EXPORT	OPENSSL_cpuid_setup,ENTRY | 
|  | .ALIGN	8 | 
|  | OPENSSL_cpuid_setup | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | bv	($rp) | 
|  | .EXIT | 
|  | nop | 
|  | .PROCEND | 
|  |  | 
|  | .EXPORT	OPENSSL_rdtsc,ENTRY | 
|  | .ALIGN	8 | 
|  | OPENSSL_rdtsc | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | mfctl	%cr16,$rv | 
|  | bv	($rp) | 
|  | .EXIT | 
|  | nop | 
|  | .PROCEND | 
|  |  | 
|  | .EXPORT	OPENSSL_wipe_cpu,ENTRY | 
|  | .ALIGN	8 | 
|  | OPENSSL_wipe_cpu | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | xor		%r0,%r0,%r1 | 
|  | fcpy,dbl	%fr0,%fr4 | 
|  | xor		%r0,%r0,%r19 | 
|  | fcpy,dbl	%fr0,%fr5 | 
|  | xor		%r0,%r0,%r20 | 
|  | fcpy,dbl	%fr0,%fr6 | 
|  | xor		%r0,%r0,%r21 | 
|  | fcpy,dbl	%fr0,%fr7 | 
|  | xor		%r0,%r0,%r22 | 
|  | fcpy,dbl	%fr0,%fr8 | 
|  | xor		%r0,%r0,%r23 | 
|  | fcpy,dbl	%fr0,%fr9 | 
|  | xor		%r0,%r0,%r24 | 
|  | fcpy,dbl	%fr0,%fr10 | 
|  | xor		%r0,%r0,%r25 | 
|  | fcpy,dbl	%fr0,%fr11 | 
|  | xor		%r0,%r0,%r26 | 
|  | fcpy,dbl	%fr0,%fr22 | 
|  | xor		%r0,%r0,%r29 | 
|  | fcpy,dbl	%fr0,%fr23 | 
|  | xor		%r0,%r0,%r31 | 
|  | fcpy,dbl	%fr0,%fr24 | 
|  | fcpy,dbl	%fr0,%fr25 | 
|  | fcpy,dbl	%fr0,%fr26 | 
|  | fcpy,dbl	%fr0,%fr27 | 
|  | fcpy,dbl	%fr0,%fr28 | 
|  | fcpy,dbl	%fr0,%fr29 | 
|  | fcpy,dbl	%fr0,%fr30 | 
|  | fcpy,dbl	%fr0,%fr31 | 
|  | bv		($rp) | 
|  | .EXIT | 
|  | ldo		0($sp),$rv | 
|  | .PROCEND | 
|  | ___ | 
|  | { | 
|  | my $inp="%r26"; | 
|  | my $len="%r25"; | 
|  |  | 
|  | $code.=<<___; | 
|  | .EXPORT	OPENSSL_cleanse,ENTRY,ARGW0=GR,ARGW1=GR | 
|  | .ALIGN	8 | 
|  | OPENSSL_cleanse | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | cmpib,*=	0,$len,L\$done | 
|  | nop | 
|  | cmpib,*>>=	15,$len,L\$ittle | 
|  | ldi		$SIZE_T-1,%r1 | 
|  |  | 
|  | L\$align | 
|  | and,*<>		$inp,%r1,%r28 | 
|  | b,n		L\$aligned | 
|  | stb		%r0,0($inp) | 
|  | ldo		-1($len),$len | 
|  | b		L\$align | 
|  | ldo		1($inp),$inp | 
|  |  | 
|  | L\$aligned | 
|  | andcm		$len,%r1,%r28 | 
|  | L\$ot | 
|  | $ST		%r0,0($inp) | 
|  | addib,*<>	-$SIZE_T,%r28,L\$ot | 
|  | ldo		$SIZE_T($inp),$inp | 
|  |  | 
|  | and,*<>		$len,%r1,$len | 
|  | b,n		L\$done | 
|  | L\$ittle | 
|  | stb		%r0,0($inp) | 
|  | addib,*<>	-1,$len,L\$ittle | 
|  | ldo		1($inp),$inp | 
|  | L\$done | 
|  | bv		($rp) | 
|  | .EXIT | 
|  | nop | 
|  | .PROCEND | 
|  | ___ | 
|  | } | 
|  | { | 
|  | my ($in1,$in2,$len)=("%r26","%r25","%r24"); | 
|  |  | 
|  | $code.=<<___; | 
|  | .EXPORT	CRYPTO_memcmp,ENTRY,ARGW0=GR,ARGW1=GR,ARGW1=GR | 
|  | .ALIGN	8 | 
|  | CRYPTO_memcmp | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | cmpib,*=	0,$len,L\$no_data | 
|  | xor		$rv,$rv,$rv | 
|  |  | 
|  | L\$oop_cmp | 
|  | ldb		0($in1),%r19 | 
|  | ldb		0($in2),%r20 | 
|  | ldo		1($in1),$in1 | 
|  | ldo		1($in2),$in2 | 
|  | xor		%r19,%r20,%r29 | 
|  | addib,*<>	-1,$len,L\$oop_cmp | 
|  | or		%r29,$rv,$rv | 
|  |  | 
|  | sub		%r0,$rv,%r29 | 
|  | extru		%r29,0,1,$rv | 
|  | L\$no_data | 
|  | bv		($rp) | 
|  | .EXIT | 
|  | nop | 
|  | .PROCEND | 
|  | ___ | 
|  | } | 
|  | { | 
|  | my ($out,$cnt,$max)=("%r26","%r25","%r24"); | 
|  | my ($tick,$lasttick)=("%r23","%r22"); | 
|  | my ($diff,$lastdiff)=("%r21","%r20"); | 
|  |  | 
|  | $code.=<<___; | 
|  | .EXPORT	OPENSSL_instrument_bus,ENTRY,ARGW0=GR,ARGW1=GR | 
|  | .ALIGN	8 | 
|  | OPENSSL_instrument_bus | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | copy		$cnt,$rv | 
|  | mfctl		%cr16,$tick | 
|  | copy		$tick,$lasttick | 
|  | ldi		0,$diff | 
|  |  | 
|  | fdc		0($out) | 
|  | ldw		0($out),$tick | 
|  | add		$diff,$tick,$tick | 
|  | stw		$tick,0($out) | 
|  | L\$oop | 
|  | mfctl		%cr16,$tick | 
|  | sub		$tick,$lasttick,$diff | 
|  | copy		$tick,$lasttick | 
|  |  | 
|  | fdc		0($out) | 
|  | ldw		0($out),$tick | 
|  | add		$diff,$tick,$tick | 
|  | stw		$tick,0($out) | 
|  |  | 
|  | addib,<>	-1,$cnt,L\$oop | 
|  | addi		4,$out,$out | 
|  |  | 
|  | bv		($rp) | 
|  | .EXIT | 
|  | sub		$rv,$cnt,$rv | 
|  | .PROCEND | 
|  |  | 
|  | .EXPORT	OPENSSL_instrument_bus2,ENTRY,ARGW0=GR,ARGW1=GR | 
|  | .ALIGN	8 | 
|  | OPENSSL_instrument_bus2 | 
|  | .PROC | 
|  | .CALLINFO	NO_CALLS | 
|  | .ENTRY | 
|  | copy		$cnt,$rv | 
|  | sub		%r0,$cnt,$cnt | 
|  |  | 
|  | mfctl		%cr16,$tick | 
|  | copy		$tick,$lasttick | 
|  | ldi		0,$diff | 
|  |  | 
|  | fdc		0($out) | 
|  | ldw		0($out),$tick | 
|  | add		$diff,$tick,$tick | 
|  | stw		$tick,0($out) | 
|  |  | 
|  | mfctl		%cr16,$tick | 
|  | sub		$tick,$lasttick,$diff | 
|  | copy		$tick,$lasttick | 
|  | L\$oop2 | 
|  | copy		$diff,$lastdiff | 
|  | fdc		0($out) | 
|  | ldw		0($out),$tick | 
|  | add		$diff,$tick,$tick | 
|  | stw		$tick,0($out) | 
|  |  | 
|  | addib,=		-1,$max,L\$done2 | 
|  | nop | 
|  |  | 
|  | mfctl		%cr16,$tick | 
|  | sub		$tick,$lasttick,$diff | 
|  | copy		$tick,$lasttick | 
|  | cmpclr,<>	$lastdiff,$diff,$tick | 
|  | ldi		1,$tick | 
|  |  | 
|  | ldi		1,%r1 | 
|  | xor		%r1,$tick,$tick | 
|  | addb,<>		$tick,$cnt,L\$oop2 | 
|  | shladd,l	$tick,2,$out,$out | 
|  | L\$done2 | 
|  | bv		($rp) | 
|  | .EXIT | 
|  | add		$rv,$cnt,$rv | 
|  | .PROCEND | 
|  | ___ | 
|  | } | 
|  |  | 
|  | if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` | 
|  | =~ /GNU assembler/) { | 
|  | $gnuas = 1; | 
|  | } | 
|  |  | 
|  | foreach(split("\n",$code)) { | 
|  |  | 
|  | s/(\.LEVEL\s+2\.0)W/$1w/	if ($gnuas && $SIZE_T==8); | 
|  | s/\.SPACE\s+\$TEXT\$/.text/	if ($gnuas && $SIZE_T==8); | 
|  | s/\.SUBSPA.*//			if ($gnuas && $SIZE_T==8); | 
|  | s/cmpib,\*/comib,/		if ($SIZE_T==4); | 
|  | s/,\*/,/			if ($SIZE_T==4); | 
|  | s/\bbv\b/bve/			if ($SIZE_T==8); | 
|  |  | 
|  | print $_,"\n"; | 
|  | } | 
|  | close STDOUT or die "error closing STDOUT: $!"; | 
|  |  |