xref: /freebsd/crypto/openssl/crypto/loongarch64cpuid.pl (revision e7be843b4a162e68651d3911f0357ed464915629)
1#! /usr/bin/env perl
2# Copyright 2022-2025 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($zero,$ra,$tp,$sp)=map("\$r$_",(0..3));
13($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$r$_",(4..11));
14($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9)=map("\$r$_",(12..21));
15($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$r$_",(23..30));
16($vr0,$vr1,$vr2,$vr3,$vr4,$vr5,$vr6,$vr7,$vr8,$vr9,$vr10,$vr11,$vr12,$vr13,$vr14,$vr15,$vr16,$vr17,$vr18,$vr19)=map("\$vr$_",(0..19));
17($fp)=map("\$r$_",(22));
18
19# $output is the last argument if it looks like a file (it has an extension)
20my $output;
21$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
22open STDOUT,">$output";
23
24{
25my ($in_a,$in_b,$len,$m,$temp1,$temp2) = ($a0,$a1,$a2,$t0,$t1,$t2);
26$code.=<<___;
27################################################################################
28# int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len)
29################################################################################
30.text
31.balign 16
32.globl CRYPTO_memcmp
33.type   CRYPTO_memcmp,\@function
34CRYPTO_memcmp:
35    li.d    $m,0
36    beqz    $len,2f   # len == 0
371:
38    ld.bu   $temp1,$in_a,0
39    ld.bu   $temp2,$in_b,0
40    addi.d  $in_a,$in_a,1
41    addi.d  $in_b,$in_b,1
42    addi.d  $len,$len,-1
43    xor     $temp1,$temp1,$temp2
44    or      $m,$m,$temp1
45    blt     $zero,$len,1b
462:
47    move    $a0,$m
48    jr      $ra
49___
50}
51{
52my ($ptr,$len,$temp1,$temp2) = ($a0,$a1,$t0,$t1);
53$code.=<<___;
54################################################################################
55# void OPENSSL_cleanse(void *ptr, size_t len)
56################################################################################
57.text
58.balign 16
59.globl OPENSSL_cleanse
60.type   OPENSSL_cleanse,\@function
61OPENSSL_cleanse:
62    beqz    $len,2f         # len == 0, return
63    srli.d  $temp1,$len,4
64    bnez    $temp1,3f       # len > 15
65
661:  # Store <= 15 individual bytes
67    st.b    $zero,$ptr,0
68    addi.d  $ptr,$ptr,1
69    addi.d  $len,$len,-1
70    bnez    $len,1b
712:
72    jr      $ra
73
743:  # Store individual bytes until we are aligned
75    andi    $temp1,$ptr,0x7
76    beqz    $temp1,4f
77    st.b    $zero,$ptr,0
78    addi.d  $ptr,$ptr,1
79    addi.d  $len,$len,-1
80    b       3b
81
824:  # Store aligned dwords
83    li.d    $temp2,8
844:
85    st.d    $zero,$ptr,0
86    addi.d  $ptr,$ptr,8
87    addi.d  $len,$len,-8
88    bge     $len,$temp2,4b  # if len>=8 loop
89    bnez    $len,1b         # if len<8 and len != 0, store remaining bytes
90    jr      $ra
91___
92}
93{
94$code.=<<___;
95################################################################################
96# uint32_t OPENSSL_rdtsc(void)
97################################################################################
98.text
99.balign 16
100.globl OPENSSL_rdtsc
101.type   OPENSSL_rdtsc,\@function
102OPENSSL_rdtsc:
103    rdtimel.w $a0,$zero
104    jr        $ra
105___
106}
107
108$code =~ s/\`([^\`]*)\`/eval($1)/gem;
109
110print $code;
111
112close STDOUT or die "error closing STDOUT: $!";
113