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 |
|
---|
39 | use strict;
|
---|
40 | use warnings;
|
---|
41 |
|
---|
42 | # Set $have_stacktrace to 1 if we have Devel::StackTrace
|
---|
43 | my $have_stacktrace = 0;
|
---|
44 | if (eval {require Devel::StackTrace;1;}) {
|
---|
45 | $have_stacktrace = 1;
|
---|
46 | }
|
---|
47 |
|
---|
48 | my @regs = map("x$_",(0..31));
|
---|
49 | # Mapping from the RISC-V psABI ABI mnemonic names to the register number.
|
---|
50 | my @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 |
|
---|
56 | my %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
|
---|
62 | sub 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.
|
---|
83 | sub 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.
|
---|
104 | sub 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.
|
---|
131 | sub 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.
|
---|
148 | sub 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 |
|
---|
164 | my @vregs = map("v$_",(0..31));
|
---|
165 | my %vreglookup;
|
---|
166 | @vreglookup{@vregs} = @vregs;
|
---|
167 |
|
---|
168 | sub 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.
|
---|
188 | sub 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 |
|
---|
210 | sub 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 |
|
---|
244 | sub 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 |
|
---|
281 | sub 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 |
|
---|
291 | sub 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 |
|
---|
301 | sub 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 |
|
---|
311 | sub 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 |
|
---|
321 | sub 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 |
|
---|
330 | sub 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 |
|
---|
340 | sub 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 |
|
---|
350 | sub 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 |
|
---|
358 | sub 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 |
|
---|
368 | sub 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 |
|
---|
378 | sub 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 |
|
---|
387 | sub 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 |
|
---|
397 | sub 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 |
|
---|
407 | sub 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 |
|
---|
419 | sub 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 |
|
---|
429 | sub 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 |
|
---|
439 | sub 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 |
|
---|
449 | sub 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 |
|
---|
459 | sub 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 |
|
---|
466 | sub 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 |
|
---|
475 | sub 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 |
|
---|
484 | sub 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 |
|
---|
493 | sub 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 |
|
---|
501 | sub 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 |
|
---|
510 | sub 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 |
|
---|
521 | sub 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 |
|
---|
530 | sub 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 |
|
---|
540 | sub 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 |
|
---|
549 | sub 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 |
|
---|
558 | sub 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 |
|
---|
567 | sub 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 |
|
---|
577 | sub 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 |
|
---|
585 | sub 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 |
|
---|
593 | sub 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 |
|
---|
601 | sub vor_vv {
|
---|
602 | # vor.vv vd, vs2, vs1
|
---|
603 | my $template = 0b0010101_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 |
|
---|
610 | sub vor_vv_v0t {
|
---|
611 | # vor.vv vd, vs2, vs1, v0.t
|
---|
612 | my $template = 0b0010100_00000_00000_000_00000_1010111;
|
---|
613 | my $vd = read_vreg shift;
|
---|
614 | my $vs2 = read_vreg shift;
|
---|
615 | my $vs1 = read_vreg shift;
|
---|
616 | return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
|
---|
617 | }
|
---|
618 |
|
---|
619 | sub vse8_v {
|
---|
620 | # vse8.v vd, (rs1), vm
|
---|
621 | my $template = 0b000000_0_00000_00000_000_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 |
|
---|
628 | sub vse32_v {
|
---|
629 | # vse32.v vd, (rs1), vm
|
---|
630 | my $template = 0b000000_0_00000_00000_110_00000_0100111;
|
---|
631 | my $vd = read_vreg shift;
|
---|
632 | my $rs1 = read_reg shift;
|
---|
633 | my $vm = read_mask_vreg shift;
|
---|
634 | return ".word ".($template | ($vm << 25) | ($rs1 << 15) | ($vd << 7));
|
---|
635 | }
|
---|
636 |
|
---|
637 | sub vssseg_nf_e32_v {
|
---|
638 | # vssseg<nf>e32.v vs3, (rs1), rs2
|
---|
639 | my $template = 0b0000101_00000_00000_110_00000_0100111;
|
---|
640 | my $nf = shift;
|
---|
641 | $nf -= 1;
|
---|
642 | my $vs3 = read_vreg shift;
|
---|
643 | my $rs1 = read_reg shift;
|
---|
644 | my $rs2 = read_reg shift;
|
---|
645 | return ".word ".($template | ($nf << 29) | ($rs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
|
---|
646 | }
|
---|
647 |
|
---|
648 | sub vsuxei8_v {
|
---|
649 | # vsuxei8.v vs3, (rs1), vs2, vm
|
---|
650 | my $template = 0b000001_0_00000_00000_000_00000_0100111;
|
---|
651 | my $vs3 = read_vreg shift;
|
---|
652 | my $rs1 = read_reg shift;
|
---|
653 | my $vs2 = read_vreg shift;
|
---|
654 | my $vm = read_mask_vreg shift;
|
---|
655 | return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
|
---|
656 | }
|
---|
657 |
|
---|
658 | sub vse64_v {
|
---|
659 | # vse64.v vd, (rs1)
|
---|
660 | my $template = 0b0000001_00000_00000_111_00000_0100111;
|
---|
661 | my $vd = read_vreg shift;
|
---|
662 | my $rs1 = read_reg shift;
|
---|
663 | return ".word ".($template | ($rs1 << 15) | ($vd << 7));
|
---|
664 | }
|
---|
665 |
|
---|
666 | sub vsetivli__x0_2_e64_m1_tu_mu {
|
---|
667 | # vsetivli x0, 2, e64, m1, tu, mu
|
---|
668 | return ".word 0xc1817057";
|
---|
669 | }
|
---|
670 |
|
---|
671 | sub vsetivli__x0_4_e32_m1_tu_mu {
|
---|
672 | # vsetivli x0, 4, e32, m1, tu, mu
|
---|
673 | return ".word 0xc1027057";
|
---|
674 | }
|
---|
675 |
|
---|
676 | sub vsetivli__x0_4_e64_m1_tu_mu {
|
---|
677 | # vsetivli x0, 4, e64, m1, tu, mu
|
---|
678 | return ".word 0xc1827057";
|
---|
679 | }
|
---|
680 |
|
---|
681 | sub vsetivli__x0_8_e32_m1_tu_mu {
|
---|
682 | # vsetivli x0, 8, e32, m1, tu, mu
|
---|
683 | return ".word 0xc1047057";
|
---|
684 | }
|
---|
685 |
|
---|
686 | sub vsetvli {
|
---|
687 | # vsetvli rd, rs1, vtypei
|
---|
688 | my $template = 0b0_00000000000_00000_111_00000_1010111;
|
---|
689 | my $rd = read_reg shift;
|
---|
690 | my $rs1 = read_reg shift;
|
---|
691 | my $sew = read_sew shift;
|
---|
692 | my $lmul = read_lmul shift;
|
---|
693 | my $tail_policy = read_tail_policy shift;
|
---|
694 | my $mask_policy = read_mask_policy shift;
|
---|
695 | my $vtypei = ($mask_policy << 7) | ($tail_policy << 6) | ($sew << 3) | $lmul;
|
---|
696 |
|
---|
697 | return ".word ".($template | ($vtypei << 20) | ($rs1 << 15) | ($rd << 7));
|
---|
698 | }
|
---|
699 |
|
---|
700 | sub vsetivli {
|
---|
701 | # vsetvli rd, uimm, vtypei
|
---|
702 | my $template = 0b11_0000000000_00000_111_00000_1010111;
|
---|
703 | my $rd = read_reg shift;
|
---|
704 | my $uimm = shift;
|
---|
705 | my $sew = read_sew shift;
|
---|
706 | my $lmul = read_lmul shift;
|
---|
707 | my $tail_policy = read_tail_policy shift;
|
---|
708 | my $mask_policy = read_mask_policy shift;
|
---|
709 | my $vtypei = ($mask_policy << 7) | ($tail_policy << 6) | ($sew << 3) | $lmul;
|
---|
710 |
|
---|
711 | return ".word ".($template | ($vtypei << 20) | ($uimm << 15) | ($rd << 7));
|
---|
712 | }
|
---|
713 |
|
---|
714 | sub vslidedown_vi {
|
---|
715 | # vslidedown.vi vd, vs2, uimm
|
---|
716 | my $template = 0b0011111_00000_00000_011_00000_1010111;
|
---|
717 | my $vd = read_vreg shift;
|
---|
718 | my $vs2 = read_vreg shift;
|
---|
719 | my $uimm = shift;
|
---|
720 | return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
|
---|
721 | }
|
---|
722 |
|
---|
723 | sub vslidedown_vx {
|
---|
724 | # vslidedown.vx vd, vs2, rs1
|
---|
725 | my $template = 0b0011111_00000_00000_100_00000_1010111;
|
---|
726 | my $vd = read_vreg shift;
|
---|
727 | my $vs2 = read_vreg shift;
|
---|
728 | my $rs1 = read_reg shift;
|
---|
729 | return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
|
---|
730 | }
|
---|
731 |
|
---|
732 | sub vslideup_vi_v0t {
|
---|
733 | # vslideup.vi vd, vs2, uimm, v0.t
|
---|
734 | my $template = 0b0011100_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 |
|
---|
741 | sub vslideup_vi {
|
---|
742 | # vslideup.vi vd, vs2, uimm
|
---|
743 | my $template = 0b0011101_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 |
|
---|
750 | sub vsll_vi {
|
---|
751 | # vsll.vi vd, vs2, uimm, vm
|
---|
752 | my $template = 0b1001011_00000_00000_011_00000_1010111;
|
---|
753 | my $vd = read_vreg shift;
|
---|
754 | my $vs2 = read_vreg shift;
|
---|
755 | my $uimm = shift;
|
---|
756 | return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
|
---|
757 | }
|
---|
758 |
|
---|
759 | sub vsrl_vi {
|
---|
760 | # vsrl.vi vd, vs2, uimm, vm
|
---|
761 | my $template = 0b1010001_00000_00000_011_00000_1010111;
|
---|
762 | my $vd = read_vreg shift;
|
---|
763 | my $vs2 = read_vreg shift;
|
---|
764 | my $uimm = shift;
|
---|
765 | return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
|
---|
766 | }
|
---|
767 |
|
---|
768 | sub vsrl_vx {
|
---|
769 | # vsrl.vx vd, vs2, rs1
|
---|
770 | my $template = 0b1010001_00000_00000_100_00000_1010111;
|
---|
771 | my $vd = read_vreg shift;
|
---|
772 | my $vs2 = read_vreg shift;
|
---|
773 | my $rs1 = read_reg shift;
|
---|
774 | return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
|
---|
775 | }
|
---|
776 |
|
---|
777 | sub vsse32_v {
|
---|
778 | # vse32.v vs3, (rs1), rs2
|
---|
779 | my $template = 0b0000101_00000_00000_110_00000_0100111;
|
---|
780 | my $vs3 = read_vreg shift;
|
---|
781 | my $rs1 = read_reg shift;
|
---|
782 | my $rs2 = read_reg shift;
|
---|
783 | return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
|
---|
784 | }
|
---|
785 |
|
---|
786 | sub vsse64_v {
|
---|
787 | # vsse64.v vs3, (rs1), rs2
|
---|
788 | my $template = 0b0000101_00000_00000_111_00000_0100111;
|
---|
789 | my $vs3 = read_vreg shift;
|
---|
790 | my $rs1 = read_reg shift;
|
---|
791 | my $rs2 = read_reg shift;
|
---|
792 | return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($vs3 << 7));
|
---|
793 | }
|
---|
794 |
|
---|
795 | sub vxor_vv_v0t {
|
---|
796 | # vxor.vv vd, vs2, vs1, v0.t
|
---|
797 | my $template = 0b0010110_00000_00000_000_00000_1010111;
|
---|
798 | my $vd = read_vreg shift;
|
---|
799 | my $vs2 = read_vreg shift;
|
---|
800 | my $vs1 = read_vreg shift;
|
---|
801 | return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
|
---|
802 | }
|
---|
803 |
|
---|
804 | sub vxor_vv {
|
---|
805 | # vxor.vv vd, vs2, vs1
|
---|
806 | my $template = 0b0010111_00000_00000_000_00000_1010111;
|
---|
807 | my $vd = read_vreg shift;
|
---|
808 | my $vs2 = read_vreg shift;
|
---|
809 | my $vs1 = read_vreg shift;
|
---|
810 | return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
|
---|
811 | }
|
---|
812 |
|
---|
813 | sub vzext_vf2 {
|
---|
814 | # vzext.vf2 vd, vs2, vm
|
---|
815 | my $template = 0b010010_0_00000_00110_010_00000_1010111;
|
---|
816 | my $vd = read_vreg shift;
|
---|
817 | my $vs2 = read_vreg shift;
|
---|
818 | my $vm = read_mask_vreg shift;
|
---|
819 | return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
|
---|
820 | }
|
---|
821 |
|
---|
822 | # Vector crypto instructions
|
---|
823 |
|
---|
824 | ## Zvbb and Zvkb instructions
|
---|
825 | ##
|
---|
826 | ## vandn (also in zvkb)
|
---|
827 | ## vbrev
|
---|
828 | ## vbrev8 (also in zvkb)
|
---|
829 | ## vrev8 (also in zvkb)
|
---|
830 | ## vclz
|
---|
831 | ## vctz
|
---|
832 | ## vcpop
|
---|
833 | ## vrol (also in zvkb)
|
---|
834 | ## vror (also in zvkb)
|
---|
835 | ## vwsll
|
---|
836 |
|
---|
837 | sub vbrev8_v {
|
---|
838 | # vbrev8.v vd, vs2, vm
|
---|
839 | my $template = 0b010010_0_00000_01000_010_00000_1010111;
|
---|
840 | my $vd = read_vreg shift;
|
---|
841 | my $vs2 = read_vreg shift;
|
---|
842 | my $vm = read_mask_vreg shift;
|
---|
843 | return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
|
---|
844 | }
|
---|
845 |
|
---|
846 | sub vrev8_v {
|
---|
847 | # vrev8.v vd, vs2, vm
|
---|
848 | my $template = 0b010010_0_00000_01001_010_00000_1010111;
|
---|
849 | my $vd = read_vreg shift;
|
---|
850 | my $vs2 = read_vreg shift;
|
---|
851 | my $vm = read_mask_vreg shift;
|
---|
852 | return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vd << 7));
|
---|
853 | }
|
---|
854 |
|
---|
855 | sub vror_vi {
|
---|
856 | # vror.vi vd, vs2, uimm
|
---|
857 | my $template = 0b01010_0_1_00000_00000_011_00000_1010111;
|
---|
858 | my $vd = read_vreg shift;
|
---|
859 | my $vs2 = read_vreg shift;
|
---|
860 | my $uimm = shift;
|
---|
861 | my $uimm_i5 = $uimm >> 5;
|
---|
862 | my $uimm_i4_0 = $uimm & 0b11111;
|
---|
863 |
|
---|
864 | return ".word ".($template | ($uimm_i5 << 26) | ($vs2 << 20) | ($uimm_i4_0 << 15) | ($vd << 7));
|
---|
865 | }
|
---|
866 |
|
---|
867 | sub vwsll_vv {
|
---|
868 | # vwsll.vv vd, vs2, vs1, vm
|
---|
869 | my $template = 0b110101_0_00000_00000_000_00000_1010111;
|
---|
870 | my $vd = read_vreg shift;
|
---|
871 | my $vs2 = read_vreg shift;
|
---|
872 | my $vs1 = read_vreg shift;
|
---|
873 | my $vm = read_mask_vreg shift;
|
---|
874 | return ".word ".($template | ($vm << 25) | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
|
---|
875 | }
|
---|
876 |
|
---|
877 | ## Zvbc instructions
|
---|
878 |
|
---|
879 | sub vclmulh_vx {
|
---|
880 | # vclmulh.vx vd, vs2, rs1
|
---|
881 | my $template = 0b0011011_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 | sub vclmul_vx_v0t {
|
---|
889 | # vclmul.vx vd, vs2, rs1, v0.t
|
---|
890 | my $template = 0b0011000_00000_00000_110_00000_1010111;
|
---|
891 | my $vd = read_vreg shift;
|
---|
892 | my $vs2 = read_vreg shift;
|
---|
893 | my $rs1 = read_reg shift;
|
---|
894 | return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
|
---|
895 | }
|
---|
896 |
|
---|
897 | sub vclmul_vx {
|
---|
898 | # vclmul.vx vd, vs2, rs1
|
---|
899 | my $template = 0b0011001_00000_00000_110_00000_1010111;
|
---|
900 | my $vd = read_vreg shift;
|
---|
901 | my $vs2 = read_vreg shift;
|
---|
902 | my $rs1 = read_reg shift;
|
---|
903 | return ".word ".($template | ($vs2 << 20) | ($rs1 << 15) | ($vd << 7));
|
---|
904 | }
|
---|
905 |
|
---|
906 | ## Zvkg instructions
|
---|
907 |
|
---|
908 | sub vghsh_vv {
|
---|
909 | # vghsh.vv vd, vs2, vs1
|
---|
910 | my $template = 0b1011001_00000_00000_010_00000_1110111;
|
---|
911 | my $vd = read_vreg shift;
|
---|
912 | my $vs2 = read_vreg shift;
|
---|
913 | my $vs1 = read_vreg shift;
|
---|
914 | return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7));
|
---|
915 | }
|
---|
916 |
|
---|
917 | sub vgmul_vv {
|
---|
918 | # vgmul.vv vd, vs2
|
---|
919 | my $template = 0b1010001_00000_10001_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 |
|
---|
925 | ## Zvkned instructions
|
---|
926 |
|
---|
927 | sub vaesdf_vs {
|
---|
928 | # vaesdf.vs vd, vs2
|
---|
929 | my $template = 0b101001_1_00000_00001_010_00000_1110111;
|
---|
930 | my $vd = read_vreg shift;
|
---|
931 | my $vs2 = read_vreg shift;
|
---|
932 | return ".word ".($template | ($vs2 << 20) | ($vd << 7));
|
---|
933 | }
|
---|
934 |
|
---|
935 | sub vaesdm_vs {
|
---|
936 | # vaesdm.vs vd, vs2
|
---|
937 | my $template = 0b101001_1_00000_00000_010_00000_1110111;
|
---|
938 | my $vd = read_vreg shift;
|
---|
939 | my $vs2 = read_vreg shift;
|
---|
940 | return ".word ".($template | ($vs2 << 20) | ($vd << 7));
|
---|
941 | }
|
---|
942 |
|
---|
943 | sub vaesef_vs {
|
---|
944 | # vaesef.vs vd, vs2
|
---|
945 | my $template = 0b101001_1_00000_00011_010_00000_1110111;
|
---|
946 | my $vd = read_vreg shift;
|
---|
947 | my $vs2 = read_vreg shift;
|
---|
948 | return ".word ".($template | ($vs2 << 20) | ($vd << 7));
|
---|
949 | }
|
---|
950 |
|
---|
951 | sub vaesem_vs {
|
---|
952 | # vaesem.vs vd, vs2
|
---|
953 | my $template = 0b101001_1_00000_00010_010_00000_1110111;
|
---|
954 | my $vd = read_vreg shift;
|
---|
955 | my $vs2 = read_vreg shift;
|
---|
956 | return ".word ".($template | ($vs2 << 20) | ($vd << 7));
|
---|
957 | }
|
---|
958 |
|
---|
959 | sub vaeskf1_vi {
|
---|
960 | # vaeskf1.vi vd, vs2, uimmm
|
---|
961 | my $template = 0b100010_1_00000_00000_010_00000_1110111;
|
---|
962 | my $vd = read_vreg shift;
|
---|
963 | my $vs2 = read_vreg shift;
|
---|
964 | my $uimm = shift;
|
---|
965 | return ".word ".($template | ($uimm << 15) | ($vs2 << 20) | ($vd << 7));
|
---|
966 | }
|
---|
967 |
|
---|
968 | sub vaeskf2_vi {
|
---|
969 | # vaeskf2.vi vd, vs2, uimm
|
---|
970 | my $template = 0b101010_1_00000_00000_010_00000_1110111;
|
---|
971 | my $vd = read_vreg shift;
|
---|
972 | my $vs2 = read_vreg shift;
|
---|
973 | my $uimm = shift;
|
---|
974 | return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
|
---|
975 | }
|
---|
976 |
|
---|
977 | sub vaesz_vs {
|
---|
978 | # vaesz.vs vd, vs2
|
---|
979 | my $template = 0b101001_1_00000_00111_010_00000_1110111;
|
---|
980 | my $vd = read_vreg shift;
|
---|
981 | my $vs2 = read_vreg shift;
|
---|
982 | return ".word ".($template | ($vs2 << 20) | ($vd << 7));
|
---|
983 | }
|
---|
984 |
|
---|
985 | ## Zvknha and Zvknhb instructions
|
---|
986 |
|
---|
987 | sub vsha2ms_vv {
|
---|
988 | # vsha2ms.vv vd, vs2, vs1
|
---|
989 | my $template = 0b1011011_00000_00000_010_00000_1110111;
|
---|
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 | sub vsha2ch_vv {
|
---|
997 | # vsha2ch.vv vd, vs2, vs1
|
---|
998 | my $template = 0b101110_10000_00000_001_00000_01110111;
|
---|
999 | my $vd = read_vreg shift;
|
---|
1000 | my $vs2 = read_vreg shift;
|
---|
1001 | my $vs1 = read_vreg shift;
|
---|
1002 | return ".word ".($template | ($vs2 << 20)| ($vs1 << 15 )| ($vd << 7));
|
---|
1003 | }
|
---|
1004 |
|
---|
1005 | sub vsha2cl_vv {
|
---|
1006 | # vsha2cl.vv vd, vs2, vs1
|
---|
1007 | my $template = 0b101111_10000_00000_001_00000_01110111;
|
---|
1008 | my $vd = read_vreg shift;
|
---|
1009 | my $vs2 = read_vreg shift;
|
---|
1010 | my $vs1 = read_vreg shift;
|
---|
1011 | return ".word ".($template | ($vs2 << 20)| ($vs1 << 15 )| ($vd << 7));
|
---|
1012 | }
|
---|
1013 |
|
---|
1014 | ## Zvksed instructions
|
---|
1015 |
|
---|
1016 | sub vsm4k_vi {
|
---|
1017 | # vsm4k.vi vd, vs2, uimm
|
---|
1018 | my $template = 0b1000011_00000_00000_010_00000_1110111;
|
---|
1019 | my $vd = read_vreg shift;
|
---|
1020 | my $vs2 = read_vreg shift;
|
---|
1021 | my $uimm = shift;
|
---|
1022 | return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7));
|
---|
1023 | }
|
---|
1024 |
|
---|
1025 | sub vsm4r_vs {
|
---|
1026 | # vsm4r.vs vd, vs2
|
---|
1027 | my $template = 0b1010011_00000_10000_010_00000_1110111;
|
---|
1028 | my $vd = read_vreg shift;
|
---|
1029 | my $vs2 = read_vreg shift;
|
---|
1030 | return ".word ".($template | ($vs2 << 20) | ($vd << 7));
|
---|
1031 | }
|
---|
1032 |
|
---|
1033 | ## zvksh instructions
|
---|
1034 |
|
---|
1035 | sub vsm3c_vi {
|
---|
1036 | # vsm3c.vi vd, vs2, uimm
|
---|
1037 | my $template = 0b1010111_00000_00000_010_00000_1110111;
|
---|
1038 | my $vd = read_vreg shift;
|
---|
1039 | my $vs2 = read_vreg shift;
|
---|
1040 | my $uimm = shift;
|
---|
1041 | return ".word ".($template | ($vs2 << 20) | ($uimm << 15 ) | ($vd << 7));
|
---|
1042 | }
|
---|
1043 |
|
---|
1044 | sub vsm3me_vv {
|
---|
1045 | # vsm3me.vv vd, vs2, vs1
|
---|
1046 | my $template = 0b1000001_00000_00000_010_00000_1110111;
|
---|
1047 | my $vd = read_vreg shift;
|
---|
1048 | my $vs2 = read_vreg shift;
|
---|
1049 | my $vs1 = read_vreg shift;
|
---|
1050 | return ".word ".($template | ($vs2 << 20) | ($vs1 << 15 ) | ($vd << 7));
|
---|
1051 | }
|
---|
1052 |
|
---|
1053 | 1;
|
---|