| #! /usr/bin/env perl |
| # Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. |
| # |
| # Licensed under the Apache License 2.0 (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 |
| |
| |
| # $output is the last argument if it looks like a file (it has an extension) |
| # $flavour is the first argument if it doesn't look like a file |
| $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; |
| $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; |
| |
| $output and 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: $!"; |
| |