Adding support for Scalar Crypto Extension (Bitmanip instructions for Cryptography, Zbkb) (#2653)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions

Introduction
This PR adds support for Zbkb extension in the CVA6 core. It also adds the documentation for this extension. These changes have been tested with self-written single instruction tests and with the riscv-arch-tests. This PR will be followed by other PRs that will add complete support for the Zkn - NIST Algorithm Suite extension.

Implementation
Zbkb Extension:
Added support for the Zbkb instruction set. It essentially expands the Zbb extension with additional instructions useful in cryptography. These instructions are pack, packh, packw, brev8, unzip and zip.

Modifications
1. A new bit ZKN was added. The complete Zkn extension will be added under this bit for ease of use. This configuration will also require the RVB (bitmanip) bit to be set.
2. Updated the ALU and decoder to recognize and handle Zbkb instructions.

Documentation and Reference
The official RISC-V Cryptography Extensions Volume I was followed to ensure alignment with ratification. The relevant documentation for the Zbkb instruction was also added.

Verification
Assembly Tests:
The instructions were tested and verified with the K module of both 32 bit and 64 bit versions of the riscv-arch-tests to ensure proper functionality. These tests check for ISA compliance, edge cases and use assertions to ensure expected behavior. The tests include:
pack-01.S
packh-01.S
packw-01.S
brev8-01.S
unzip-01.S
zip-01.S
This commit is contained in:
Munail Waqar 2024-12-19 02:35:41 +05:00 committed by GitHub
parent b5caf14c50
commit f7dd49efa5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 297 additions and 21 deletions

View file

@ -1,2 +1,2 @@
cv32a65x:
gates: 187456
gates: 188149

View file

@ -22,6 +22,7 @@
|Zbc | RVZbc Carry-less multiplication | Carry-less multiplication is the multiplication in the polynomial ring over GF(2).clmul produces the lower half of the carry-less product and clmulh produces the upper half of the 2✕XLEN carry-less product.clmulr produces bits 2✕XLEN2:XLEN-1 of the 2✕XLEN carry-less product.
|Zbs | RVZbs Single bit Instructions | The single-bit instructions provide a mechanism to set, clear, invert, or extract a single bit in a register. The bit is specified by its index.
|Zicntr | Zicntr | No info found yet for extension Zicntr
|Zbkb | RVZbkb Bitmanip instructions for Cryptography | The Zbkb extension is a part of the RISC-V Bit-Manipulation (bitmanip) extensions, specifically targeting cryptographic applications. It introduces a set of instructions designed to facilitate operations commonly used in cryptographic algorithms, such as interleaving, packing, and reordering of bits.
|===
==== RV32I Base Integer Instructions
@ -220,4 +221,3 @@
| BSET | bset rd, rs1, rs2 | X(rd) = X(rs1) \| (1 << (X(rs2) & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit set at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2. | Single_bit_Operations
| BSETI | bseti rd, rs1, shamt | X(rd) = X(rs1) \| (1 << (shamt & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit set at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved. | Single_bit_Operations
|===

View file

@ -47,6 +47,8 @@ Instructions
+---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Zicntr | Zicntr_ | No info found yet for extension Zicntr |
+---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Zbkb | RVZbkb Bitmanip instructions for Cryptography_ | The Zbkb extension is a part of the RISC-V Bit-Manipulation (bitmanip) extensions, specifically targeting cryptographic applications. It introduces a set of instructions designed to facilitate operations commonly used in cryptographic algorithms, such as interleaving, packing, and reordering of bits. |
+---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
RV32I Base Integer Instructions
-------------------------------
@ -393,4 +395,3 @@ RVZbs Single bit Instructions
+--------+----------------------+------------------------------------------------+------------------+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+
| BSETI | bseti rd, rs1, shamt | X(rd) = X(rs1) | (1 << (shamt & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit set at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved. | Single_bit_Operations |
+--------+----------------------+------------------------------------------------+------------------+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+

View file

@ -51,6 +51,9 @@ module alu
logic lz_tz_empty, lz_tz_wempty;
logic [CVA6Cfg.XLEN-1:0] orcbw_result, rev8w_result;
logic [CVA6Cfg.XLEN-1:0] brev8_reversed;
logic [ 31:0] unzip_gen;
logic [ 31:0] zip_gen;
// bit reverse operand_a for left shifts and bit counting
generate
genvar k;
@ -263,6 +266,29 @@ module alu
end
end
// ZKN gen block
if (CVA6Cfg.ZKN && CVA6Cfg.RVB) begin : zkn_gen_block
genvar i, m, n;
// Generate brev8_reversed by reversing bits within each byte
for (i = 0; i < (CVA6Cfg.XLEN / 8); i++) begin : brev8_gen
for (m = 0; m < 8; m++) begin : reverse_bits
// Reversing the order of bits within a single byte
assign brev8_reversed[(i<<3)+m] = fu_data_i.operand_a[(i<<3)+(7-m)];
end
end
// Generate zip and unzip results
if (CVA6Cfg.IS_XLEN32) begin
for (n = 0; n < 16; n++) begin : zip_unzip_gen
// Assigning lower and upper half of operand into the even and odd positions of result
assign zip_gen[n<<1] = fu_data_i.operand_a[n];
assign zip_gen[(n<<1)+1] = fu_data_i.operand_a[n+16];
// Assigning even and odd bits of operand into lower and upper halves of result
assign unzip_gen[n] = fu_data_i.operand_a[n<<1];
assign unzip_gen[n+16] = fu_data_i.operand_a[(n<<1)+1];
end
end
end
// -----------
// Result MUX
// -----------
@ -358,5 +384,22 @@ module alu
default: ; // default case to suppress unique warning
endcase
end
// ZKN instructions
if (CVA6Cfg.ZKN && CVA6Cfg.RVB) begin
unique case (fu_data_i.operation)
PACK:
result_o = (CVA6Cfg.IS_XLEN32) ? ({fu_data_i.operand_b[15:0], fu_data_i.operand_a[15:0]}) : ({fu_data_i.operand_b[31:0], fu_data_i.operand_a[31:0]});
PACK_H:
result_o = (CVA6Cfg.IS_XLEN32) ? ({16'b0, fu_data_i.operand_b[7:0], fu_data_i.operand_a[7:0]}) : ({48'b0, fu_data_i.operand_b[7:0], fu_data_i.operand_a[7:0]});
BREV8: result_o = brev8_reversed;
default: ;
endcase
if (fu_data_i.operation == PACK_W && CVA6Cfg.IS_XLEN64)
result_o = {
{32{fu_data_i.operand_b[15]}}, {fu_data_i.operand_b[15:0]}, {fu_data_i.operand_a[15:0]}
};
if (fu_data_i.operation == UNZIP && CVA6Cfg.IS_XLEN32) result_o = unzip_gen;
if (fu_data_i.operation == ZIP && CVA6Cfg.IS_XLEN32) result_o = zip_gen;
end
end
endmodule

View file

@ -776,12 +776,19 @@ module decoder
// Bitwise Shifting
{7'b011_0000, 3'b001} : instruction_o.op = ariane_pkg::ROL; // rol
{7'b011_0000, 3'b101} : instruction_o.op = ariane_pkg::ROR; // ror
{
7'b000_0100, 3'b111
} : begin
if (CVA6Cfg.ZKN) instruction_o.op = ariane_pkg::PACK_H; //packh
else illegal_instr_bm = 1'b1;
end
// Zero Extend Op RV32 encoding
{
7'b000_0100, 3'b100
} : begin
if (!CVA6Cfg.IS_XLEN64 && instr.instr[24:20] == 5'b00000)
instruction_o.op = ariane_pkg::ZEXTH;
instruction_o.op = ariane_pkg::ZEXTH; // Zero Extend Op RV32 encoding
else if (CVA6Cfg.ZKN) instruction_o.op = ariane_pkg::PACK; // pack
else illegal_instr_bm = 1'b1;
end
default: begin
@ -843,21 +850,21 @@ module decoder
instr.rtype.funct7, instr.rtype.funct3
})
// Shift with Add (Unsigned Word)
{7'b001_0000, 3'b010}: instruction_o.op = ariane_pkg::SH1ADDUW; // sh1add.uw
{7'b001_0000, 3'b100}: instruction_o.op = ariane_pkg::SH2ADDUW; // sh2add.uw
{7'b001_0000, 3'b110}: instruction_o.op = ariane_pkg::SH3ADDUW; // sh3add.uw
{7'b001_0000, 3'b010} : instruction_o.op = ariane_pkg::SH1ADDUW; // sh1add.uw
{7'b001_0000, 3'b100} : instruction_o.op = ariane_pkg::SH2ADDUW; // sh2add.uw
{7'b001_0000, 3'b110} : instruction_o.op = ariane_pkg::SH3ADDUW; // sh3add.uw
// Unsigned word Op's
{7'b000_0100, 3'b000}: instruction_o.op = ariane_pkg::ADDUW; // add.uw
{7'b000_0100, 3'b000} : instruction_o.op = ariane_pkg::ADDUW; // add.uw
// Bitwise Shifting
{7'b011_0000, 3'b001}: instruction_o.op = ariane_pkg::ROLW; // rolw
{7'b011_0000, 3'b101}: instruction_o.op = ariane_pkg::RORW; // rorw
// Zero Extend Op RV64 encoding
{7'b000_0100, 3'b100}:
begin
{7'b011_0000, 3'b001} : instruction_o.op = ariane_pkg::ROLW; // rolw
{7'b011_0000, 3'b101} : instruction_o.op = ariane_pkg::RORW; // rorw
{
7'b000_0100, 3'b100
} : begin
if (instr.instr[24:20] == 5'b00000)
instruction_o.op = ariane_pkg::ZEXTH;
else
illegal_instr_bm = 1'b1;
instruction_o.op = ariane_pkg::ZEXTH; // Zero Extend Op RV64 encoding
else if (CVA6Cfg.ZKN) instruction_o.op = ariane_pkg::PACK_W; // packw
else illegal_instr_bm = 1'b1;
end
default: illegal_instr_bm = 1'b1;
endcase
@ -912,6 +919,8 @@ module decoder
end else if (instr.instr[31:26] == 6'b010010) instruction_o.op = ariane_pkg::BCLRI;
else if (instr.instr[31:26] == 6'b011010) instruction_o.op = ariane_pkg::BINVI;
else if (instr.instr[31:26] == 6'b001010) instruction_o.op = ariane_pkg::BSETI;
else if (CVA6Cfg.ZKN && instr.instr[31:20] == 12'b000010001111)
instruction_o.op = ariane_pkg::ZIP;
else illegal_instr_bm = 1'b1;
end
3'b101: begin
@ -922,6 +931,10 @@ module decoder
instruction_o.op = ariane_pkg::REV8;
else if (instr.instr[31:26] == 6'b010_010) instruction_o.op = ariane_pkg::BEXTI;
else if (instr.instr[31:26] == 6'b011_000) instruction_o.op = ariane_pkg::RORI;
else if (CVA6Cfg.ZKN && instr.instr[31:20] == 12'b011010000111)
instruction_o.op = ariane_pkg::BREV8;
else if (CVA6Cfg.ZKN && instr.instr[31:20] == 12'b000010001111)
instruction_o.op = ariane_pkg::UNZIP;
else illegal_instr_bm = 1'b1;
end
default: illegal_instr_bm = 1'b1;

View file

@ -489,7 +489,16 @@ package ariane_pkg;
ACCEL_OP_STORE,
// Zicond instruction
CZERO_EQZ,
CZERO_NEZ
CZERO_NEZ,
// Pack instructions
PACK,
PACK_H,
PACK_W,
// Brev8 instruction
BREV8,
// Zip instructions
UNZIP,
ZIP
} fu_op;
function automatic logic op_is_branch(input fu_op op);

View file

@ -65,6 +65,7 @@ package build_config_pkg;
cfg.XF8 = CVA6Cfg.XF8;
cfg.RVA = CVA6Cfg.RVA;
cfg.RVB = CVA6Cfg.RVB;
cfg.ZKN = CVA6Cfg.ZKN;
cfg.RVV = CVA6Cfg.RVV;
cfg.RVC = CVA6Cfg.RVC;
cfg.RVH = CVA6Cfg.RVH;

View file

@ -54,6 +54,8 @@ package config_pkg;
bit RVA;
// Bit manipulation RISC-V extension
bit RVB;
// Scalar Cryptography RISC-V entension
bit ZKN;
// Vector RISC-V extension
bit RVV;
// Compress RISC-V extension
@ -240,6 +242,7 @@ package config_pkg;
bit XF8;
bit RVA;
bit RVB;
bit ZKN;
bit RVV;
bit RVC;
bit RVH;

View file

@ -39,6 +39,7 @@ package cva6_config_pkg;
XF8: bit'(0),
RVA: bit'(0),
RVB: bit'(1),
ZKN: bit'(0),
RVV: bit'(0),
RVC: bit'(1),
RVH: bit'(0),

View file

@ -39,6 +39,7 @@ package cva6_config_pkg;
XF8: bit'(0),
RVA: bit'(0),
RVB: bit'(1),
ZKN: bit'(0),
RVV: bit'(0),
RVC: bit'(1),
RVH: bit'(0),

View file

@ -90,6 +90,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -24,7 +24,6 @@ package cva6_config_pkg;
localparam CVA6ConfigZcmpExtEn = 0;
localparam CVA6ConfigAExtEn = 1;
localparam CVA6ConfigHExtEn = 0; // always disabled
localparam CVA6ConfigBExtEn = 0;
localparam CVA6ConfigVExtEn = 0;
localparam CVA6ConfigRVZiCond = 0;
@ -90,7 +89,8 @@ package cva6_config_pkg;
XF16ALT: bit'(CVA6ConfigF16AltEn),
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
RVB: bit'(1),
ZKN: bit'(1),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(1),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -98,6 +98,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(1),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -91,6 +91,7 @@ package cva6_config_pkg;
XF8: bit'(CVA6ConfigF8En),
RVA: bit'(CVA6ConfigAExtEn),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVH: bit'(CVA6ConfigHExtEn),

View file

@ -46,6 +46,7 @@ package cva6_config_pkg;
XF8: bit'(0),
RVA: bit'(0),
RVB: bit'(CVA6ConfigBExtEn),
ZKN: bit'(0),
RVV: bit'(0),
RVC: bit'(1),
RVH: bit'(0),

View file

@ -0,0 +1,168 @@
..
Copyright (c) 2023 OpenHW Group
Copyright (c) 2023 10xEngineers
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
.. Level 1
=======
Level 2
-------
Level 3
~~~~~~~
Level 4
^^^^^^^
.. _cva6_riscv_instructions_RV32Zbkb:
*Applicability of this chapter to configurations:*
.. csv-table::
:widths: auto
:align: left
:header: "Configuration", "Implementation"
"CV32A60AX", "Implemented extension"
"CV64A6_MMU", "Implemented extension"
=============================
RVZbkb: Bitmanip instructions for Cryptography
=============================
The following instructions comprise the Zbkb extension:
Pack instructions
--------------------
The Pack instructions can be implemented by packing the lower halves of both source operands into the destination register for pack and packw instructions and by packing the lower bytes of the source operands into the destination register for packh.
+-----------+-----------+-----------------------+
| RV32 | RV64 | Mnemonic |
+===========+===========+=======================+
| ✔ | ✔ | pack rd, rs1, rs2 |
+-----------+-----------+-----------------------+
| ✔ | ✔ | packh rd, rs1, rs2 |
+-----------+-----------+-----------------------+
| | ✔ | packw rd, rs1, rs2 |
+-----------+-----------+-----------------------+
RV32 and RV64 Instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~
- **PACK**: Pack low halves of registers
**Format**: pack rd, rs1, rs2
**Description**: This instruction packs the lower halves of rs1 and rs2 into rd, with rs1 in the lower half and rs2 in the upper half.
**Pseudocode**: X(rd) = X(rs2)[XLEN/2-1..0] @ X(rs1)[XLEN/2-1..0];
**Invalid values**: NONE
**Exception raised**: NONE
- **PACKH**: Pack low bytes of registers
**Format**: packh rd, rs1, rs2
**Description**: This instruction packs the least-significant bytes of rs1 and rs2 into the 16 least-significant bits of rd, zero extending the rest of rd.
**Pseudocode**: X(rd) = EXTZ(X(rs2)[7..0] @ X(rs1)[7..0]);
**Invalid values**: NONE
**Exception raised**: NONE
RV64 specific instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~
- **PACKW**: Pack low 16-bits of registers
**Format**: packw rd, rs1, rs2
**Description**: This instruction packs the low 16 bits of rs1 and rs2 into the 32 least-significant bits of rd, sign extending the 32-bit result to the rest of rd.
**Pseudocode**: X(rd) = EXTS(X(rs2)[15..0] @ X(rs1)[15..0]);
**Invalid values**: NONE
**Exception raised**: NONE
Zip instructions
--------------------------------
These instructions are used to extract bits from the source registers and interleave them into the destination register.
+-----------+-----------+-----------------------+
| RV32 | RV64 | Mnemonic |
+===========+===========+=======================+
| ✔ | | zip rd, rs |
+-----------+-----------+-----------------------+
| ✔ | | unzip rd, rs |
+-----------+-----------+-----------------------+
RV32 specific Instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~
- **ZIP**: Zip
**Format**: zip rd, rs
**Description**: This instruction places bits in the low half of the source register into the even bit positions of the destination, and bits in the high half of the source register into the odd bit positions of the destination. It is the inverse of the unzip instruction.
**Pseudocode**: foreach (i from 0 to 15) {
X(rd)[i << 1] = X(rs1)[i]
X(rd)[i+1 << 1] = X(rs1)[i+16]
}
**Invalid values**: NONE
**Exception raised**: NONE
- **UNZIP**: Unzip
**Format**: unzip rd, rs
**Description**: This instruction places the even bits of the source register into the low half of the destination, and the odd bits of the source into the high bits of the destination. It is the inverse of the zip instruction.
**Pseudocode**: foreach (i from 0 to 15) {
X(rd)[i] = X(rs1)[i << 1]
X(rd)[i+16] = X(rs1)[i+1 << 1]
}
**Invalid values**: NONE
**Exception raised**: NONE
Bits-in-Byte-reverse
------------
brev8 reverses the bits in each byte of the source register.
+-----------+-----------+-----------------------+
| RV32 | RV64 | Mnemonic |
+===========+===========+=======================+
| ✔ | ✔ | brev8 rd, rs |
+-----------+-----------+-----------------------+
RV32 and RV64 Instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~
- **BREV8**: Reverse bits in bytes
**Format**: brev8 rd, rs
**Description**: This instruction reverses the order of the bits in every byte of a register.
**Pseudocode**: foreach (i from 0 to xlen by 8) {
foreach (j from 0 to 7) {
X(rd)[(i<<3)+j] = X(rs)[(i<<3)+(7-j)];
}
}
**Invalid values**: NONE
**Exception raised**: NONE

View file

@ -877,9 +877,12 @@ def load_config(args, cwd):
if base in ("cv64a6_imafdch_sv39", "cv64a6_imafdch_sv39_wb"):
args.mabi = "lp64d"
args.isa = "rv64gch_zba_zbb_zbs_zbc"
elif base in ("cv64a6_imafdc_sv39", "cv64a6_imafdc_sv39_hpdcache", "cv64a6_imafdc_sv39_wb"):
elif base in ("cv64a6_imafdc_sv39_wb"):
args.mabi = "lp64d"
args.isa = "rv64gc_zba_zbb_zbs_zbc"
elif base in ("cv64a6_imafdc_sv39", "cv64a6_imafdc_sv39_hpdcache"):
args.mabi = "lp64d"
args.isa = "rv64gc_zba_zbb_zbs_zbc_zbkb"
elif base == "cv32a60x":
args.mabi = "ilp32"
args.isa = "rv32imc_zba_zbb_zbs_zbc"
@ -896,7 +899,7 @@ def load_config(args, cwd):
args.isa = "rv32imac"
elif base == "cv32a6_imac_sv32":
args.mabi = "ilp32"
args.isa = "rv32imac"
args.isa = "rv32imac_zbkb"
elif base == "cv32a6_imafc_sv32":
args.mabi = "ilp32f"
args.isa = "rv32imafc"

View file

@ -967,3 +967,23 @@ testlist:
iterations: 1
<<: *common_test_config
asm_tests: <path_var>/riscv-arch-test/riscv-test-suite/rv64i_m/A/src/amoxor.w-01.S
- test: rv64im-pack-01
<<: *common_test_config
iterations: 1
asm_tests: <path_var>/riscv-arch-test/riscv-test-suite/rv64i_m/K/src/pack-01.S
- test: rv64im-packh-01
<<: *common_test_config
iterations: 1
asm_tests: <path_var>/riscv-arch-test/riscv-test-suite/rv64i_m/K/src/packh-01.S
- test: rv64im-packw-01
<<: *common_test_config
iterations: 1
asm_tests: <path_var>/riscv-arch-test/riscv-test-suite/rv64i_m/K/src/packw-01.S
- test: rv64im-brev8-01
<<: *common_test_config
iterations: 1
asm_tests: <path_var>/riscv-arch-test/riscv-test-suite/rv64i_m/K/src/brev8-01.S