VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/crypto/perlasm/riscv.pm

Last change on this file was 108206, checked in by vboxsync, 3 months ago

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 30.5 KB
Line 
1#! /usr/bin/env perl
2# This file is dual-licensed, meaning that you can use it under your
3# choice of either of the following two licenses:
4#
5# Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
6#
7# Licensed under the Apache License 2.0 (the "License"). You can obtain
8# a copy in the file LICENSE in the source distribution or at
9# https://www.openssl.org/source/license.html
10#
11# or
12#
13# Copyright (c) 2023, Christoph Müllner <[email protected]>
14# Copyright (c) 2023, Jerry Shih <[email protected]>
15# Copyright (c) 2023, Phoebe Chen <[email protected]>
16# All rights reserved.
17#
18# Redistribution and use in source and binary forms, with or without
19# modification, are permitted provided that the following conditions
20# are met:
21# 1. Redistributions of source code must retain the above copyright
22# notice, this list of conditions and the following disclaimer.
23# 2. Redistributions in binary form must reproduce the above copyright
24# notice, this list of conditions and the following disclaimer in the
25# documentation and/or other materials provided with the distribution.
26#
27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39use strict;
40use warnings;
41
42# Set $have_stacktrace to 1 if we have Devel::StackTrace
43my $have_stacktrace = 0;
44if (eval {require Devel::StackTrace;1;}) {
45 $have_stacktrace = 1;
46}
47
48my @regs = map("x$_",(0..31));
49# Mapping from the RISC-V psABI ABI mnemonic names to the register number.
50my @regaliases = ('zero','ra','sp','gp','tp','t0','t1','t2','s0','s1',
51 map("a$_",(0..7)),
52 map("s$_",(2..11)),
53 map("t$_",(3..6))
54);
55
56my %reglookup;
57@reglookup{@regs} = @regs;
58@reglookup{@regaliases} = @regs;
59
60# Takes a register name, possibly an alias, and converts it to a register index
61# from 0 to 31
62sub read_reg {
63 my $reg = lc shift;
64 if (!exists($reglookup{$reg})) {
65 my $trace = "";
66 if ($have_stacktrace) {
67 $trace = Devel::StackTrace->new->as_string;
68 }
69 die("Unknown register ".$reg."\n".$trace);
70 }
71 my $regstr = $reglookup{$reg};
72 if (!($regstr =~ /^x([0-9]+)$/)) {
73 my $trace = "";
74 if ($have_stacktrace) {
75 $trace = Devel::StackTrace->new->as_string;
76 }
77 die("Could not process register ".$reg."\n".$trace);
78 }
79 return $1;
80}
81
82# Read the sew setting(8, 16, 32 and 64) and convert to vsew encoding.
83sub read_sew {
84 my $sew_setting = shift;
85
86 if ($sew_setting eq "e8") {
87 return 0;
88 } elsif ($sew_setting eq "e16") {
89 return 1;
90 } elsif ($sew_setting eq "e32") {
91 return 2;
92 } elsif ($sew_setting eq "e64") {
93 return 3;
94 } else {
95 my $trace = "";
96 if ($have_stacktrace) {
97 $trace = Devel::StackTrace->new->as_string;
98 }
99 die("Unsupported SEW setting:".$sew_setting."\n".$trace);
100 }
101}
102
103# Read the LMUL settings and convert to vlmul encoding.
104sub read_lmul {
105 my $lmul_setting = shift;
106
107 if ($lmul_setting eq "mf8") {
108 return 5;
109 } elsif ($lmul_setting eq "mf4") {
110 return 6;
111 } elsif ($lmul_setting eq "mf2") {
112 return 7;
113 } elsif ($lmul_setting eq "m1") {
114 return 0;
115 } elsif ($lmul_setting eq "m2") {
116 return 1;
117 } elsif ($lmul_setting eq "m4") {
118 return 2;
119 } elsif ($lmul_setting eq "m8") {
120 return 3;
121 } else {
122 my $trace = "";
123 if ($have_stacktrace) {
124 $trace = Devel::StackTrace->new->as_string;
125 }
126 die("Unsupported LMUL setting:".$lmul_setting."\n".$trace);
127 }
128}
129
130# Read the tail policy settings and convert to vta encoding.
131sub read_tail_policy {
132 my $tail_setting = shift;
133
134 if ($tail_setting eq "ta") {
135 return 1;
136 } elsif ($tail_setting eq "tu") {
137 return 0;
138 } else {
139 my $trace = "";
140 if ($have_stacktrace) {
141 $trace = Devel::StackTrace->new->as_string;
142 }
143 die("Unsupported tail policy setting:".$tail_setting."\n".$trace);
144 }
145}
146
147# Read the mask policy settings and convert to vma encoding.
148sub read_mask_policy {
149 my $mask_setting = shift;
150
151 if ($mask_setting eq "ma") {
152 return 1;
153 } elsif ($mask_setting eq "mu") {
154 return 0;
155 } else {
156 my $trace = "";
157 if ($have_stacktrace) {
158 $trace = Devel::StackTrace->new->as_string;
159 }
160 die("Unsupported mask policy setting:".$mask_setting."\n".$trace);
161 }
162}
163
164my @vregs = map("v$_",(0..31));
165my %vreglookup;
166@vreglookup{@vregs} = @vregs;
167
168sub read_vreg {
169 my $vreg = lc shift;
170 if (!exists($vreglookup{$vreg})) {
171 my $trace = "";
172 if ($have_stacktrace) {
173 $trace = Devel::StackTrace->new->as_string;
174 }
175 die("Unknown vector register ".$vreg."\n".$trace);
176 }
177 if (!($vreg =~ /^v([0-9]+)$/)) {
178 my $trace = "";
179 if ($have_stacktrace) {
180 $trace = Devel::StackTrace->new->as_string;
181 }
182 die("Could not process vector register ".$vreg."\n".$trace);
183 }
184 return $1;
185}
186
187# Read the vm settings and convert to mask encoding.
188sub read_mask_vreg {
189 my $vreg = shift;
190 # The default value is unmasked.
191 my $mask_bit = 1;
192
193 if (defined($vreg)) {
194 my $reg_id = read_vreg $vreg;
195 if ($reg_id == 0) {
196 $mask_bit = 0;
197 } else {
198 my $trace = "";
199 if ($have_stacktrace) {
200 $trace = Devel::StackTrace->new->as_string;
201 }
202 die("The ".$vreg." is not the mask register v0.\n".$trace);
203 }
204 }
205 return $mask_bit;
206}
207
208# Helper functions
209
210sub brev8_rv64i {
211 # brev8 without `brev8` instruction (only in Zbkb)
212 # Bit-reverses the first argument and needs two scratch registers
213 my $val = shift;
214 my $t0 = shift;
215 my $t1 = shift;
216 my $brev8_const = shift;
217 my $seq = <<___;
218 la $brev8_const, Lbrev8_const
219
220 ld $t0, 0($brev8_const) # 0xAAAAAAAAAAAAAAAA
221 slli $t1, $val, 1
222 and $t1, $t1, $t0
223 and $val, $val, $t0
224 srli $val, $val, 1
225 or $val, $t1, $val
226
227 ld $t0, 8($brev8_const) # 0xCCCCCCCCCCCCCCCC
228 slli $t1, $val, 2
229 and $t1, $t1, $t0
230 and $val, $val, $t0
231 srli $val, $val, 2
232 or $val, $t1, $val
233
234 ld $t0, 16($brev8_const) # 0xF0F0F0F0F0F0F0F0
235 slli $t1, $val, 4
236 and $t1, $t1, $t0
237 and $val, $val, $t0
238 srli $val, $val, 4
239 or $val, $t1, $val
240___
241 return $seq;
242}
243
244sub sd_rev8_rv64i {
245 # rev8 without `rev8` instruction (only in Zbb or Zbkb)
246 # Stores the given value byte-reversed and needs one scratch register
247 my $val = shift;
248 my $addr = shift;
249 my $off = shift;
250 my $tmp = shift;
251 my $off0 = ($off + 0);
252 my $off1 = ($off + 1);
253 my $off2 = ($off + 2);
254 my $off3 = ($off + 3);
255 my $off4 = ($off + 4);
256 my $off5 = ($off + 5);
257 my $off6 = ($off + 6);
258 my $off7 = ($off + 7);
259 my $seq = <<___;
260 sb $val, $off7($addr)
261 srli $tmp, $val, 8
262 sb $tmp, $off6($addr)
263 srli $tmp, $val, 16
264 sb $tmp, $off5($addr)
265 srli $tmp, $val, 24
266 sb $tmp, $off4($addr)
267 srli $tmp, $val, 32
268 sb $tmp, $off3($addr)
269 srli $tmp, $val, 40
270 sb $tmp, $off2($addr)
271 srli $tmp, $val, 48
272 sb $tmp, $off1($addr)
273 srli $tmp, $val, 56
274 sb $tmp, $off0($addr)
275___
276 return $seq;
277}
278
279# Scalar crypto instructions
280
281sub aes64ds {
282 # Encoding for aes64ds rd, rs1, rs2 instruction on RV64
283 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
284 my $template = 0b0011101_00000_00000_000_00000_0110011;
285 my $rd = read_reg shift;
286 my $rs1 = read_reg shift;
287 my $rs2 = read_reg shift;
288 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
289}
290
291sub aes64dsm {
292 # Encoding for aes64dsm rd, rs1, rs2 instruction on RV64
293 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
294 my $template = 0b0011111_00000_00000_000_00000_0110011;
295 my $rd = read_reg shift;
296 my $rs1 = read_reg shift;
297 my $rs2 = read_reg shift;
298 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
299}
300
301sub aes64es {
302 # Encoding for aes64es rd, rs1, rs2 instruction on RV64
303 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
304 my $template = 0b0011001_00000_00000_000_00000_0110011;
305 my $rd = read_reg shift;
306 my $rs1 = read_reg shift;
307 my $rs2 = read_reg shift;
308 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
309}
310
311sub aes64esm {
312 # Encoding for aes64esm rd, rs1, rs2 instruction on RV64
313 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
314 my $template = 0b0011011_00000_00000_000_00000_0110011;
315 my $rd = read_reg shift;
316 my $rs1 = read_reg shift;
317 my $rs2 = read_reg shift;
318 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
319}
320
321sub aes64im {
322 # Encoding for aes64im rd, rs1 instruction on RV64
323 # XXXXXXXXXXXX_ rs1 _XXX_ rd _XXXXXXX
324 my $template = 0b001100000000_00000_001_00000_0010011;
325 my $rd = read_reg shift;
326 my $rs1 = read_reg shift;
327 return ".word ".($template | ($rs1 << 15) | ($rd << 7));
328}
329
330sub aes64ks1i {
331 # Encoding for aes64ks1i rd, rs1, rnum instruction on RV64
332 # XXXXXXXX_rnum_ rs1 _XXX_ rd _XXXXXXX
333 my $template = 0b00110001_0000_00000_001_00000_0010011;
334 my $rd = read_reg shift;
335 my $rs1 = read_reg shift;
336 my $rnum = shift;
337 return ".word ".($template | ($rnum << 20) | ($rs1 << 15) | ($rd << 7));
338}
339
340sub aes64ks2 {
341 # Encoding for aes64ks2 rd, rs1, rs2 instruction on RV64
342 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
343 my $template = 0b0111111_00000_00000_000_00000_0110011;
344 my $rd = read_reg shift;
345 my $rs1 = read_reg shift;
346 my $rs2 = read_reg shift;
347 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
348}
349
350sub brev8 {
351 # brev8 rd, rs
352 my $template = 0b011010000111_00000_101_00000_0010011;
353 my $rd = read_reg shift;
354 my $rs = read_reg shift;
355 return ".word ".($template | ($rs << 15) | ($rd << 7));
356}
357
358sub clmul {
359 # Encoding for clmul rd, rs1, rs2 instruction on RV64
360 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
361 my $template = 0b0000101_00000_00000_001_00000_0110011;
362 my $rd = read_reg shift;
363 my $rs1 = read_reg shift;
364 my $rs2 = read_reg shift;
365 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
366}
367
368sub clmulh {
369 # Encoding for clmulh rd, rs1, rs2 instruction on RV64
370 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
371 my $template = 0b0000101_00000_00000_011_00000_0110011;
372 my $rd = read_reg shift;
373 my $rs1 = read_reg shift;
374 my $rs2 = read_reg shift;
375 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
376}
377
378sub rev8 {
379 # Encoding for rev8 rd, rs instruction on RV64
380 # XXXXXXXXXXXXX_ rs _XXX_ rd _XXXXXXX
381 my $template = 0b011010111000_00000_101_00000_0010011;
382 my $rd = read_reg shift;
383 my $rs = read_reg shift;
384 return ".word ".($template | ($rs << 15) | ($rd << 7));
385}
386
387sub roriw {
388 # Encoding for roriw rd, rs1, shamt instruction on RV64
389 # XXXXXXX_ shamt _ rs1 _XXX_ rd _XXXXXXX
390 my $template = 0b0110000_00000_00000_101_00000_0011011;
391 my $rd = read_reg shift;
392 my $rs1 = read_reg shift;
393 my $shamt = shift;
394 return ".word ".($template | ($shamt << 20) | ($rs1 << 15) | ($rd << 7));
395}
396
397sub maxu {
398 # Encoding for maxu rd, rs1, rs2 instruction on RV64
399 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
400 my $template = 0b0000101_00000_00000_111_00000_0110011;
401 my $rd = read_reg shift;
402 my $rs1 = read_reg shift;
403 my $rs2 = read_reg shift;
404 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
405}
406
407sub minu {
408 # Encoding for minu rd, rs1, rs2 instruction on RV64
409 # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX
410 my $template = 0b0000101_00000_00000_101_00000_0110011;
411 my $rd = read_reg shift;
412 my $rs1 = read_reg shift;
413 my $rs2 = read_reg shift;
414 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7));
415}
416
417# Vector instructions
418
419sub vadd_vv {
420 # vadd.vv vd, vs2, vs1, vm
421 my $template = 0b000000_0_00000_00000_000_00000_1010111;
422 my $vd = read_vreg shift;
423 my $vs2 = read_vreg shift;
424 my $vs1 = read_vreg shift;
425 my $vm = read_mask_vreg shift;
426 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
427}
428
429sub vadd_vx {
430 # vadd.vx vd, vs2, rs1, vm
431 my $template = 0b000000_0_00000_00000_100_00000_1010111;
432 my $vd = read_vreg shift;
433 my $vs2 = read_vreg shift;
434 my $rs1 = read_reg shift;
435 my $vm = read_mask_vreg shift;
436 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
437}
438
439sub vsub_vv {
440 # vsub.vv vd, vs2, vs1, vm
441 my $template = 0b000010_0_00000_00000_000_00000_1010111;
442 my $vd = read_vreg shift;
443 my $vs2 = read_vreg shift;
444 my $vs1 = read_vreg shift;
445 my $vm = read_mask_vreg shift;
446 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
447}
448
449sub vsub_vx {
450 # vsub.vx vd, vs2, rs1, vm
451 my $template = 0b000010_0_00000_00000_100_00000_1010111;
452 my $vd = read_vreg shift;
453 my $vs2 = read_vreg shift;
454 my $rs1 = read_reg shift;
455 my $vm = read_mask_vreg shift;
456 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
457}
458
459sub vid_v {
460 # vid.v vd
461 my $template = 0b0101001_00000_10001_010_00000_1010111;
462 my $vd = read_vreg shift;
463 return ".word ".($template | ($vd << 7));
464}
465
466sub viota_m {
467 # viota.m vd, vs2, vm
468 my $template = 0b010100_0_00000_10000_010_00000_1010111;
469 my $vd = read_vreg shift;
470 my $vs2 = read_vreg shift;
471 my $vm = read_mask_vreg shift;
472 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
473}
474
475sub vle8_v {
476 # vle8.v vd, (rs1), vm
477 my $template = 0b000000_0_00000_00000_000_00000_0000111;
478 my $vd = read_vreg shift;
479 my $rs1 = read_reg shift;
480 my $vm = read_mask_vreg shift;
481 return ".word ".($template | ($vm << 25) | ($rs1 << 15) | ($vd << 7));
482}
483
484sub vle32_v {
485 # vle32.v vd, (rs1), vm
486 my $template = 0b000000_0_00000_00000_110_00000_0000111;
487 my $vd = read_vreg shift;
488 my $rs1 = read_reg shift;
489 my $vm = read_mask_vreg shift;
490 return ".word ".($template | ($vm << 25) | ($rs1 << 15) | ($vd << 7));
491}
492
493sub vle64_v {
494 # vle64.v vd, (rs1)
495 my $template = 0b0000001_00000_00000_111_00000_0000111;
496 my $vd = read_vreg shift;
497 my $rs1 = read_reg shift;
498 return ".word ".($template | ($rs1 << 15) | ($vd << 7));
499}
500
501sub vlse32_v {
502 # vlse32.v vd, (rs1), rs2
503 my $template = 0b0000101_00000_00000_110_00000_0000111;
504 my $vd = read_vreg shift;
505 my $rs1 = read_reg shift;
506 my $rs2 = read_reg shift;
507 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($vd << 7));
508}
509
510sub vlsseg_nf_e32_v {
511 # vlsseg<nf>e32.v vd, (rs1), rs2
512 my $template = 0b0000101_00000_00000_110_00000_0000111;
513 my $nf = shift;
514 $nf -= 1;
515 my $vd = read_vreg shift;
516 my $rs1 = read_reg shift;
517 my $rs2 = read_reg shift;
518 return ".word ".($template | ($nf << 29) | ($rs2 << 20) | ($rs1 << 15) | ($vd << 7));
519}
520
521sub vlse64_v {
522 # vlse64.v vd, (rs1), rs2
523 my $template = 0b0000101_00000_00000_111_00000_0000111;
524 my $vd = read_vreg shift;
525 my $rs1 = read_reg shift;
526 my $rs2 = read_reg shift;
527 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($vd << 7));
528}
529
530sub vluxei8_v {
531 # vluxei8.v vd, (rs1), vs2, vm
532 my $template = 0b000001_0_00000_00000_000_00000_0000111;
533 my $vd = read_vreg shift;
534 my $rs1 = read_reg shift;
535 my $vs2 = read_vreg shift;
536 my $vm = read_mask_vreg shift;
537 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
538}
539
540sub vmerge_vim {
541 # vmerge.vim vd, vs2, imm, v0
542 my $template = 0b0101110_00000_00000_011_00000_1010111;
543 my $vd = read_vreg shift;
544 my $vs2 = read_vreg shift;
545 my $imm = shift;
546 return ".word ".($template | ($vs2 << 20) | ($imm << 15) | ($vd << 7));
547}
548
549sub vmerge_vvm {
550 # vmerge.vvm vd vs2 vs1
551 my $template = 0b0101110_00000_00000_000_00000_1010111;
552 my $vd = read_vreg shift;
553 my $vs2 = read_vreg shift;
554 my $vs1 = read_vreg shift;
555 return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7))
556}
557
558sub vmseq_vi {
559 # vmseq.vi vd vs1, imm
560 my $template = 0b0110001_00000_00000_011_00000_1010111;
561 my $vd = read_vreg shift;
562 my $vs1 = read_vreg shift;
563 my $imm = shift;
564 return ".word ".($template | ($vs1 << 20) | ($imm << 15) | ($vd << 7))
565}
566
567sub vmsgtu_vx {
568 # vmsgtu.vx vd vs2, rs1, vm
569 my $template = 0b011110_0_00000_00000_100_00000_1010111;
570 my $vd = read_vreg shift;
571 my $vs2 = read_vreg shift;
572 my $rs1 = read_reg shift;
573 my $vm = read_mask_vreg shift;
574 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7))
575}
576
577sub vmv_v_i {
578 # vmv.v.i vd, imm
579 my $template = 0b0101111_00000_00000_011_00000_1010111;
580 my $vd = read_vreg shift;
581 my $imm = shift;
582 return ".word ".($template | ($imm << 15) | ($vd << 7));
583}
584
585sub vmv_v_x {
586 # vmv.v.x vd, rs1
587 my $template = 0b0101111_00000_00000_100_00000_1010111;
588 my $vd = read_vreg shift;
589 my $rs1 = read_reg shift;
590 return ".word ".($template | ($rs1 << 15) | ($vd << 7));
591}
592
593sub vmv_v_v {
594 # vmv.v.v vd, vs1
595 my $template = 0b0101111_00000_00000_000_00000_1010111;
596 my $vd = read_vreg shift;
597 my $vs1 = read_vreg shift;
598 return ".word ".($template | ($vs1 << 15) | ($vd << 7));
599}
600
601sub vor_vv_v0t {
602 # vor.vv vd, vs2, vs1, v0.t
603 my $template = 0b0010100_00000_00000_000_00000_1010111;
604 my $vd = read_vreg shift;
605 my $vs2 = read_vreg shift;
606 my $vs1 = read_vreg shift;
607 return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
608}
609
610sub vse8_v {
611 # vse8.v vd, (rs1), vm
612 my $template = 0b000000_0_00000_00000_000_00000_0100111;
613 my $vd = read_vreg shift;
614 my $rs1 = read_reg shift;
615 my $vm = read_mask_vreg shift;
616 return ".word ".($template | ($vm << 25) | ($rs1 << 15) | ($vd << 7));
617}
618
619sub vse32_v {
620 # vse32.v vd, (rs1), vm
621 my $template = 0b000000_0_00000_00000_110_00000_0100111;
622 my $vd = read_vreg shift;
623 my $rs1 = read_reg shift;
624 my $vm = read_mask_vreg shift;
625 return ".word ".($template | ($vm << 25) | ($rs1 << 15) | ($vd << 7));
626}
627
628sub vssseg_nf_e32_v {
629 # vssseg<nf>e32.v vs3, (rs1), rs2
630 my $template = 0b0000101_00000_00000_110_00000_0100111;
631 my $nf = shift;
632 $nf -= 1;
633 my $vs3 = read_vreg shift;
634 my $rs1 = read_reg shift;
635 my $rs2 = read_reg shift;
636 return ".word ".($template | ($nf << 29) | ($rs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
637}
638
639sub vsuxei8_v {
640 # vsuxei8.v vs3, (rs1), vs2, vm
641 my $template = 0b000001_0_00000_00000_000_00000_0100111;
642 my $vs3 = read_vreg shift;
643 my $rs1 = read_reg shift;
644 my $vs2 = read_vreg shift;
645 my $vm = read_mask_vreg shift;
646 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
647}
648
649sub vse64_v {
650 # vse64.v vd, (rs1)
651 my $template = 0b0000001_00000_00000_111_00000_0100111;
652 my $vd = read_vreg shift;
653 my $rs1 = read_reg shift;
654 return ".word ".($template | ($rs1 << 15) | ($vd << 7));
655}
656
657sub vsetivli__x0_2_e64_m1_tu_mu {
658 # vsetivli x0, 2, e64, m1, tu, mu
659 return ".word 0xc1817057";
660}
661
662sub vsetivli__x0_4_e32_m1_tu_mu {
663 # vsetivli x0, 4, e32, m1, tu, mu
664 return ".word 0xc1027057";
665}
666
667sub vsetivli__x0_4_e64_m1_tu_mu {
668 # vsetivli x0, 4, e64, m1, tu, mu
669 return ".word 0xc1827057";
670}
671
672sub vsetivli__x0_8_e32_m1_tu_mu {
673 # vsetivli x0, 8, e32, m1, tu, mu
674 return ".word 0xc1047057";
675}
676
677sub vsetvli {
678 # vsetvli rd, rs1, vtypei
679 my $template = 0b0_00000000000_00000_111_00000_1010111;
680 my $rd = read_reg shift;
681 my $rs1 = read_reg shift;
682 my $sew = read_sew shift;
683 my $lmul = read_lmul shift;
684 my $tail_policy = read_tail_policy shift;
685 my $mask_policy = read_mask_policy shift;
686 my $vtypei = ($mask_policy << 7) | ($tail_policy << 6) | ($sew << 3) | $lmul;
687
688 return ".word ".($template | ($vtypei << 20) | ($rs1 << 15) | ($rd << 7));
689}
690
691sub vsetivli {
692 # vsetvli rd, uimm, vtypei
693 my $template = 0b11_0000000000_00000_111_00000_1010111;
694 my $rd = read_reg shift;
695 my $uimm = shift;
696 my $sew = read_sew shift;
697 my $lmul = read_lmul shift;
698 my $tail_policy = read_tail_policy shift;
699 my $mask_policy = read_mask_policy shift;
700 my $vtypei = ($mask_policy << 7) | ($tail_policy << 6) | ($sew << 3) | $lmul;
701
702 return ".word ".($template | ($vtypei << 20) | ($uimm << 15) | ($rd << 7));
703}
704
705sub vslidedown_vi {
706 # vslidedown.vi vd, vs2, uimm
707 my $template = 0b0011111_00000_00000_011_00000_1010111;
708 my $vd = read_vreg shift;
709 my $vs2 = read_vreg shift;
710 my $uimm = shift;
711 return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
712}
713
714sub vslidedown_vx {
715 # vslidedown.vx vd, vs2, rs1
716 my $template = 0b0011111_00000_00000_100_00000_1010111;
717 my $vd = read_vreg shift;
718 my $vs2 = read_vreg shift;
719 my $rs1 = read_reg shift;
720 return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
721}
722
723sub vslideup_vi_v0t {
724 # vslideup.vi vd, vs2, uimm, v0.t
725 my $template = 0b0011100_00000_00000_011_00000_1010111;
726 my $vd = read_vreg shift;
727 my $vs2 = read_vreg shift;
728 my $uimm = shift;
729 return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
730}
731
732sub vslideup_vi {
733 # vslideup.vi vd, vs2, uimm
734 my $template = 0b0011101_00000_00000_011_00000_1010111;
735 my $vd = read_vreg shift;
736 my $vs2 = read_vreg shift;
737 my $uimm = shift;
738 return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
739}
740
741sub vsll_vi {
742 # vsll.vi vd, vs2, uimm, vm
743 my $template = 0b1001011_00000_00000_011_00000_1010111;
744 my $vd = read_vreg shift;
745 my $vs2 = read_vreg shift;
746 my $uimm = shift;
747 return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
748}
749
750sub vsrl_vx {
751 # vsrl.vx vd, vs2, rs1
752 my $template = 0b1010001_00000_00000_100_00000_1010111;
753 my $vd = read_vreg shift;
754 my $vs2 = read_vreg shift;
755 my $rs1 = read_reg shift;
756 return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
757}
758
759sub vsse32_v {
760 # vse32.v vs3, (rs1), rs2
761 my $template = 0b0000101_00000_00000_110_00000_0100111;
762 my $vs3 = read_vreg shift;
763 my $rs1 = read_reg shift;
764 my $rs2 = read_reg shift;
765 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
766}
767
768sub vsse64_v {
769 # vsse64.v vs3, (rs1), rs2
770 my $template = 0b0000101_00000_00000_111_00000_0100111;
771 my $vs3 = read_vreg shift;
772 my $rs1 = read_reg shift;
773 my $rs2 = read_reg shift;
774 return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
775}
776
777sub vxor_vv_v0t {
778 # vxor.vv vd, vs2, vs1, v0.t
779 my $template = 0b0010110_00000_00000_000_00000_1010111;
780 my $vd = read_vreg shift;
781 my $vs2 = read_vreg shift;
782 my $vs1 = read_vreg shift;
783 return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
784}
785
786sub vxor_vv {
787 # vxor.vv vd, vs2, vs1
788 my $template = 0b0010111_00000_00000_000_00000_1010111;
789 my $vd = read_vreg shift;
790 my $vs2 = read_vreg shift;
791 my $vs1 = read_vreg shift;
792 return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
793}
794
795sub vzext_vf2 {
796 # vzext.vf2 vd, vs2, vm
797 my $template = 0b010010_0_00000_00110_010_00000_1010111;
798 my $vd = read_vreg shift;
799 my $vs2 = read_vreg shift;
800 my $vm = read_mask_vreg shift;
801 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
802}
803
804# Vector crypto instructions
805
806## Zvbb and Zvkb instructions
807##
808## vandn (also in zvkb)
809## vbrev
810## vbrev8 (also in zvkb)
811## vrev8 (also in zvkb)
812## vclz
813## vctz
814## vcpop
815## vrol (also in zvkb)
816## vror (also in zvkb)
817## vwsll
818
819sub vbrev8_v {
820 # vbrev8.v vd, vs2, vm
821 my $template = 0b010010_0_00000_01000_010_00000_1010111;
822 my $vd = read_vreg shift;
823 my $vs2 = read_vreg shift;
824 my $vm = read_mask_vreg shift;
825 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
826}
827
828sub vrev8_v {
829 # vrev8.v vd, vs2, vm
830 my $template = 0b010010_0_00000_01001_010_00000_1010111;
831 my $vd = read_vreg shift;
832 my $vs2 = read_vreg shift;
833 my $vm = read_mask_vreg shift;
834 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
835}
836
837sub vror_vi {
838 # vror.vi vd, vs2, uimm
839 my $template = 0b01010_0_1_00000_00000_011_00000_1010111;
840 my $vd = read_vreg shift;
841 my $vs2 = read_vreg shift;
842 my $uimm = shift;
843 my $uimm_i5 = $uimm >> 5;
844 my $uimm_i4_0 = $uimm & 0b11111;
845
846 return ".word ".($template | ($uimm_i5 << 26) | ($vs2 << 20) | ($uimm_i4_0 << 15) | ($vd << 7));
847}
848
849sub vwsll_vv {
850 # vwsll.vv vd, vs2, vs1, vm
851 my $template = 0b110101_0_00000_00000_000_00000_1010111;
852 my $vd = read_vreg shift;
853 my $vs2 = read_vreg shift;
854 my $vs1 = read_vreg shift;
855 my $vm = read_mask_vreg shift;
856 return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
857}
858
859## Zvbc instructions
860
861sub vclmulh_vx {
862 # vclmulh.vx vd, vs2, rs1
863 my $template = 0b0011011_00000_00000_110_00000_1010111;
864 my $vd = read_vreg shift;
865 my $vs2 = read_vreg shift;
866 my $rs1 = read_reg shift;
867 return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
868}
869
870sub vclmul_vx_v0t {
871 # vclmul.vx vd, vs2, rs1, v0.t
872 my $template = 0b0011000_00000_00000_110_00000_1010111;
873 my $vd = read_vreg shift;
874 my $vs2 = read_vreg shift;
875 my $rs1 = read_reg shift;
876 return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
877}
878
879sub vclmul_vx {
880 # vclmul.vx vd, vs2, rs1
881 my $template = 0b0011001_00000_00000_110_00000_1010111;
882 my $vd = read_vreg shift;
883 my $vs2 = read_vreg shift;
884 my $rs1 = read_reg shift;
885 return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
886}
887
888## Zvkg instructions
889
890sub vghsh_vv {
891 # vghsh.vv vd, vs2, vs1
892 my $template = 0b1011001_00000_00000_010_00000_1110111;
893 my $vd = read_vreg shift;
894 my $vs2 = read_vreg shift;
895 my $vs1 = read_vreg shift;
896 return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
897}
898
899sub vgmul_vv {
900 # vgmul.vv vd, vs2
901 my $template = 0b1010001_00000_10001_010_00000_1110111;
902 my $vd = read_vreg shift;
903 my $vs2 = read_vreg shift;
904 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
905}
906
907## Zvkned instructions
908
909sub vaesdf_vs {
910 # vaesdf.vs vd, vs2
911 my $template = 0b101001_1_00000_00001_010_00000_1110111;
912 my $vd = read_vreg shift;
913 my $vs2 = read_vreg shift;
914 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
915}
916
917sub vaesdm_vs {
918 # vaesdm.vs vd, vs2
919 my $template = 0b101001_1_00000_00000_010_00000_1110111;
920 my $vd = read_vreg shift;
921 my $vs2 = read_vreg shift;
922 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
923}
924
925sub vaesef_vs {
926 # vaesef.vs vd, vs2
927 my $template = 0b101001_1_00000_00011_010_00000_1110111;
928 my $vd = read_vreg shift;
929 my $vs2 = read_vreg shift;
930 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
931}
932
933sub vaesem_vs {
934 # vaesem.vs vd, vs2
935 my $template = 0b101001_1_00000_00010_010_00000_1110111;
936 my $vd = read_vreg shift;
937 my $vs2 = read_vreg shift;
938 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
939}
940
941sub vaeskf1_vi {
942 # vaeskf1.vi vd, vs2, uimmm
943 my $template = 0b100010_1_00000_00000_010_00000_1110111;
944 my $vd = read_vreg shift;
945 my $vs2 = read_vreg shift;
946 my $uimm = shift;
947 return ".word ".($template | ($uimm << 15) | ($vs2 << 20) | ($vd << 7));
948}
949
950sub vaeskf2_vi {
951 # vaeskf2.vi vd, vs2, uimm
952 my $template = 0b101010_1_00000_00000_010_00000_1110111;
953 my $vd = read_vreg shift;
954 my $vs2 = read_vreg shift;
955 my $uimm = shift;
956 return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
957}
958
959sub vaesz_vs {
960 # vaesz.vs vd, vs2
961 my $template = 0b101001_1_00000_00111_010_00000_1110111;
962 my $vd = read_vreg shift;
963 my $vs2 = read_vreg shift;
964 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
965}
966
967## Zvknha and Zvknhb instructions
968
969sub vsha2ms_vv {
970 # vsha2ms.vv vd, vs2, vs1
971 my $template = 0b1011011_00000_00000_010_00000_1110111;
972 my $vd = read_vreg shift;
973 my $vs2 = read_vreg shift;
974 my $vs1 = read_vreg shift;
975 return ".word ".($template | ($vs2 << 20)| ($vs1 << 15 )| ($vd << 7));
976}
977
978sub vsha2ch_vv {
979 # vsha2ch.vv vd, vs2, vs1
980 my $template = 0b101110_10000_00000_001_00000_01110111;
981 my $vd = read_vreg shift;
982 my $vs2 = read_vreg shift;
983 my $vs1 = read_vreg shift;
984 return ".word ".($template | ($vs2 << 20)| ($vs1 << 15 )| ($vd << 7));
985}
986
987sub vsha2cl_vv {
988 # vsha2cl.vv vd, vs2, vs1
989 my $template = 0b101111_10000_00000_001_00000_01110111;
990 my $vd = read_vreg shift;
991 my $vs2 = read_vreg shift;
992 my $vs1 = read_vreg shift;
993 return ".word ".($template | ($vs2 << 20)| ($vs1 << 15 )| ($vd << 7));
994}
995
996## Zvksed instructions
997
998sub vsm4k_vi {
999 # vsm4k.vi vd, vs2, uimm
1000 my $template = 0b1000011_00000_00000_010_00000_1110111;
1001 my $vd = read_vreg shift;
1002 my $vs2 = read_vreg shift;
1003 my $uimm = shift;
1004 return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
1005}
1006
1007sub vsm4r_vs {
1008 # vsm4r.vs vd, vs2
1009 my $template = 0b1010011_00000_10000_010_00000_1110111;
1010 my $vd = read_vreg shift;
1011 my $vs2 = read_vreg shift;
1012 return ".word ".($template | ($vs2 << 20) | ($vd << 7));
1013}
1014
1015## zvksh instructions
1016
1017sub vsm3c_vi {
1018 # vsm3c.vi vd, vs2, uimm
1019 my $template = 0b1010111_00000_00000_010_00000_1110111;
1020 my $vd = read_vreg shift;
1021 my $vs2 = read_vreg shift;
1022 my $uimm = shift;
1023 return ".word ".($template | ($vs2 << 20) | ($uimm << 15 ) | ($vd << 7));
1024}
1025
1026sub vsm3me_vv {
1027 # vsm3me.vv vd, vs2, vs1
1028 my $template = 0b1000001_00000_00000_010_00000_1110111;
1029 my $vd = read_vreg shift;
1030 my $vs2 = read_vreg shift;
1031 my $vs1 = read_vreg shift;
1032 return ".word ".($template | ($vs2 << 20) | ($vs1 << 15 ) | ($vd << 7));
1033}
1034
10351;
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette