openssl/crypto/riscv64cpuid.pl
Christoph Müllner cdea67193d riscv: Add basic vector extension support
The RISC-V vector extension comes with an implementation-defined
number of bits per vector register (VLEN), which can be read out at
run-time using the CSR 'vlenb' (which returns VLEN/8) followed by a
multiplication by 8 (to convert bytes to bits).

This patch introduces a RISC-V capability 'V' to specify the
availability of the vector extension. If this extension is found at
run-time, then we read out VLEN as described above and cache it.
Caching ensures that we only read the CSR once at startup.
This is necessary because reading out CSR can be expensive
(e.g. if CSR readout is implemented using trap-and-emulate).

Follow-up patches can make use of VLEN and chose the best strategy
based on the available length of the vector registers.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21923)
2023-10-26 15:55:49 +01:00

106 lines
2.8 KiB
Raku

#! /usr/bin/env perl
# Copyright 2022 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";
{
my ($in_a,$in_b,$len,$x,$temp1,$temp2) = ('a0','a1','a2','t0','t1','t2');
$code.=<<___;
################################################################################
# int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len)
################################################################################
.text
.balign 16
.globl CRYPTO_memcmp
.type CRYPTO_memcmp,\@function
CRYPTO_memcmp:
li $x,0
beqz $len,2f # len == 0
1:
lbu $temp1,0($in_a)
lbu $temp2,0($in_b)
addi $in_a,$in_a,1
addi $in_b,$in_b,1
addi $len,$len,-1
xor $temp1,$temp1,$temp2
or $x,$x,$temp1
bgtz $len,1b
2:
mv a0,$x
ret
___
}
{
my ($ptr,$len,$temp1,$temp2) = ('a0','a1','t0','t1');
$code.=<<___;
################################################################################
# void OPENSSL_cleanse(void *ptr, size_t len)
################################################################################
.text
.balign 16
.globl OPENSSL_cleanse
.type OPENSSL_cleanse,\@function
OPENSSL_cleanse:
beqz $len,2f # len == 0, return
srli $temp1,$len,4
bnez $temp1,3f # len > 15
1: # Store <= 15 individual bytes
sb x0,0($ptr)
addi $ptr,$ptr,1
addi $len,$len,-1
bnez $len,1b
2:
ret
3: # Store individual bytes until we are aligned
andi $temp1,$ptr,0x7
beqz $temp1,4f
sb x0,0($ptr)
addi $ptr,$ptr,1
addi $len,$len,-1
j 3b
4: # Store aligned dwords
li $temp2,8
4:
sd x0,0($ptr)
addi $ptr,$ptr,8
addi $len,$len,-8
bge $len,$temp2,4b # if len>=8 loop
bnez $len,1b # if len<8 and len != 0, store remaining bytes
ret
___
}
{
my ($ret) = ('a0');
$code .= <<___;
################################################################################
# size_t riscv_vlen_asm(void)
# Return VLEN (i.e. the length of a vector register in bits).
.p2align 3
.globl riscv_vlen_asm
.type riscv_vlen_asm,\@function
riscv_vlen_asm:
csrr $ret, vlenb
slli $ret, $ret, 3
ret
.size riscv_vlen_asm,.-riscv_vlen_asm
___
}
print $code;
close STDOUT or die "error closing STDOUT: $!";