Skip to main content

11 Bit Manipulation Extensions

The bit-manipulation (bitmanip) extension collection is comprised of several component extensions to the base RISC-V architecture that are intended to provide some combination of code-size reduction, performance improvement, and energy reduction. While the instructions are intended for general use, some instructions are more useful in certain domains than in others. Hence, several smaller bitmanip extensions are provided. Each of these smaller extensions is grouped by common function and use case, and each has its own Zb*-extension name.

Each bitmanip extension includes a group of several bitmanip instructions that have similar purposes and can often share the same logic. Some instructions are available in only one extension, while others are available in several. The instructions have mnemonics and encodings that are independent of the extensions in which they appear. Thus, when implementing extensions with overlapping instructions, there is no redundancy in logic or encoding.

The bitmanip extensions are defined for RV32 and RV64.

The bitmanip extension follows the convention in RV64 that w-suffixed instructions (without a dot before the w) ignore the upper 32 bits of their inputs, operate on the least-significant 32 bits as signed values, and produce a 32-bit signed result that is sign-extended to XLEN.

Bitmanip instructions with the suffix .uw have one operand that is an unsigned 32-bit value that is extracted from the least-significant 32 bits of the specified register. Other than that, these perform full-XLEN operations.

Bitmanip instructions with the suffixes .b, .h, and .w only look at the least-significant 8 bits, 16 bits, and 32 bits of the input (respectively) and produce an XLEN-wide result that is sign-extended or zero-extended, based on the specific instruction.

The bit-manipulation instructions comprise the following extensions:

Below is a list of all of the instructions that are included in these extensions, along with their specific mapping:

RV32RV64MnemonicInstructionZbbZbkbZbcZbkc
andn rd, rs1, rs2insns-andn
brev8 rd, rsinsns-brev8
clmul rd, rs1, rs2insns-clmul
clmulh rd, rs1, rs2insns-clmulh
clmulr rd, rs1, rs2insns-clmulr
clz rd, rsinsns-clz
clzw rd, rsinsns-clzw
cpop rd, rsinsns-cpop
cpopw rd, rsinsns-cpopw
ctz rd, rsinsns-ctz
ctzw rd, rsinsns-ctzw
max rd, rs1, rs2insns-max
maxu rd, rs1, rs2insns-maxu
min rd, rs1, rs2insns-min
minu rd, rs1, rs2insns-minu
orc.b rd, rsinsns-orc_b
orn rd, rs1, rs2insns-orn
pack rd, rs1, rs2insns-pack
packh rd, rs1, rs2insns-packh
packw rd, rs1, rs2insns-packw
rev8 rd, rsinsns-rev8
rol rd, rs1, rs2insns-rol
rolw rd, rs1, rs2insns-rolw
ror rd, rs1, rs2insns-ror
rori rd, rs1, shamtinsns-rori
roriw rd, rs1, shamtinsns-roriw
rorw rd, rs1, rs2insns-rorw
sext.b rd, rsinsns-sext_b
sext.h rd, rsinsns-sext_h
unzip rd, rsinsns-unzip
xnor rd, rs1, rs2insns-xnor
zext.h rd, rsinsns-zext_h
zip rd, rsinsns-zip
RV32RV64MnemonicInstructionZbaZbs
add.uw rd, rs1, rs2insns-add_uw
bclr rd, rs1, rs2insns-bclr
bclri rd, rs1, imminsns-bclri
bext rd, rs1, rs2insns-bext
bexti rd, rs1, imminsns-bexti
binv rd, rs1, rs2insns-binv
binvi rd, rs1, imminsns-binvi
bset rd, rs1, rs2insns-bset
bseti rd, rs1, imminsns-bseti
sh1add rd, rs1, rs2insns-sh1add
sh1add.uw rd, rs1, rs2insns-sh1add_uw
sh2add rd, rs1, rs2insns-sh2add
sh2add.uw rd, rs1, rs2insns-sh2add_uw
sh3add rd, rs1, rs2insns-sh3add
sh3add.uw rd, rs1, rs2insns-sh3add_uw
slli.uw rd, rs1, imminsns-slli_uw

11.1 "B" Extension for Bit Manipulation, Version 1.0.0

The B standard extension comprises instructions provided by the Zba, Zbb, and Zbs extensions.

11.2 Zba: Extension for Address generation, Version 1.0.0

The Zba instructions can be used to accelerate the generation of addresses that index into arrays of basic types (halfword, word, doubleword) using both unsigned word-sized and XLEN-sized indices: a shifted index is added to a base address.

The shift and add instructions do a left shift of 1, 2, or 3 because these are commonly found in real-world code and because they can be implemented with a minimal amount of additional hardware beyond that of the simple adder. This avoids lengthening the critical path in implementations.

While the shift and add instructions are limited to a maximum left shift of 3, the slli instruction (from the base ISA) can be used to perform similar shifts for indexing into arrays of wider elements. The slli.uw — added in this extension — can be used when the index is to be interpreted as an unsigned word.

The following instructions comprise the Zba extension:

RV32RV64MnemonicInstruction
add.uw rd, rs1, rs2insns-add_uw
sh1add rd, rs1, rs2insns-sh1add
sh1add.uw rd, rs1, rs2insns-sh1add_uw
sh2add rd, rs1, rs2insns-sh2add
sh2add.uw rd, rs1, rs2insns-sh2add_uw
sh3add rd, rs1, rs2insns-sh3add
sh3add.uw rd, rs1, rs2insns-sh3add_uw
slli.uw rd, rs1, imminsns-slli_uw

11.3 Zbb: Extension for Basic bit-manipulation, Version 1.0.0

11.3.1 Logical with negate

RV32RV64MnemonicInstruction
andn rd, rs1, rs2insns-andn
orn rd, rs1, rs2insns-orn
xnor rd, rs1, rs2insns-xnor
note

The Logical with Negate instructions can be implemented by inverting the rs2 inputs to the base-required AND, OR, and XOR logic instructions. In some implementations, the inverter on rs2 used for subtraction can be reused for this purpose.

11.3.2 Count leading/trailing zero bits

RV32RV64MnemonicInstruction
clz rd, rsinsns-clz
clzw rd, rsinsns-clzw
ctz rd, rsinsns-ctz
ctzw rd, rsinsns-ctzw

11.3.3 Count population

These instructions count the number of set bits (1-bits). This is also commonly referred to as population count.

RV32RV64MnemonicInstruction
cpop rd, rsinsns-cpop
cpopw rd, rsinsns-cpopw

11.3.4 Integer minimum/maximum

The integer minimum/maximum instructions are arithmetic R-type instructions that return the smaller/larger of two operands.

RV32RV64MnemonicInstruction
max rd, rs1, rs2insns-max
maxu rd, rs1, rs2insns-maxu
min rd, rs1, rs2insns-min
minu rd, rs1, rs2insns-minu

11.3.5 Sign extension and zero extension

These instructions perform the sign extension or zero extension of the least-significant 8 bits or 16 bits of the source register.

These instructions replace the generalized idioms slli rd,rs,(XLEN-\<size>) + srai (for sign extension of 8-bit and 16-bit quantities) and slli + srli (for zero extension of 16-bit quantities).

RV32RV64MnemonicInstruction
sext.b rd, rsinsns-sext_b
sext.h rd, rsinsns-sext_h
zext.h rd, rsinsns-zext_h

11.3.6 Bitwise rotation

Bitwise rotation instructions are similar to the shift-logical operations from the base spec. However, where the shift-logical instructions shift in zeros, the rotate instructions shift in the bits that were shifted out of the other side of the value. Such operations are also referred to as ‘circular shifts’.

RV32RV64MnemonicInstruction
rol rd, rs1, rs2insns-rol
rolw rd, rs1, rs2insns-rolw
ror rd, rs1, rs2insns-ror
rori rd, rs1, shamtinsns-rori
roriw rd, rs1, shamtinsns-roriw
rorw rd, rs1, rs2insns-rorw
note

The rotate instructions were included to replace a common four-instruction sequence to achieve the same effect (neg; sll/srl; srl/sll; or)

11.3.7 OR Combine

orc.b sets the bits of each byte in the result rd to all zeros if no bit within the respective byte of rs is set, or to all ones if any bit within the respective byte of rs is set.

One use-case is string-processing functions, such as strlen and strcpy, which can use orc.b to test for the terminating zero byte by counting the set bits in leading non-zero bytes in a word.

RV32RV64MnemonicInstruction
orc.b rd, rsinsns-orc_b

11.3.8 Byte-reverse

rev8 reverses the byte-ordering of rs.

RV32RV64MnemonicInstruction
rev8 rd, rsinsns-rev8

11.4 Zbc: Extension for Carry-less multiplication, Version 1.0.0

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×XLEN−2:XLEN-1 of the 2×XLEN carry-less product.

RV32RV64MnemonicInstruction
clmul rd, rs1, rs2insns-clmul
clmulh rd, rs1, rs2insns-clmulh
clmulr rd, rs1, rs2insns-clmulr

11.5 Zbs: Extension for Single-bit instructions, Version 1.0.0

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.

RV32RV64MnemonicInstruction
bclr rd, rs1, rs2insns-bclr
bclri rd, rs1, imminsns-bclri
bext rd, rs1, rs2insns-bext
bexti rd, rs1, imminsns-bexti
binv rd, rs1, rs2insns-binv
binvi rd, rs1, imminsns-binvi
bset rd, rs1, rs2insns-bset
bseti rd, rs1, imminsns-bseti

11.6 Zbkb: Extension for Bit-manipulation for Cryptography, Version 1.0.0

This extension contains instructions essential for implementing common operations in cryptographic workloads.

RV32RV64MnemonicInstruction
rolinsns-rol
rolwinsns-rolw
rorinsns-ror
roriinsns-rori
roriwinsns-roriw
rorwinsns-rorw
andninsns-andn
orninsns-orn
xnorinsns-xnor
packinsns-pack
packhinsns-packh
packwinsns-packw
brev8insns-brev8
rev8insns-rev8
zipinsns-zip
unzipinsns-unzip

11.7 Zbkc: Extension for Carry-less multiplication for Cryptography, Version 1.0.0

Carry-less multiplication is the multiplication in the polynomial ring over GF(2). This extension is a subset of the Zbc zbc extension, and only provides clmul and clmulh. These are the crucial instructions needed to efficiently implement the GHASH operation, a critical operation in some cryptographic workloads such as the AES-GCM authenticated encryption scheme. See Zbc zbc for further instruction details for these two instructions.

11.8 Zbkx: Extension for Crossbar permutations, Version 1.0.0

These instructions implement a "lookup table" for 4 and 8 bit elements inside the general purpose registers. rs1 is used as a vector of N-bit words, and rs2 as a vector of N-bit indices into rs1. Elements in rs1 are replaced by the indexed element in rs2, or zero if the index into rs2 is out of bounds.

These instructions are useful for expressing N-bit to N-bit boolean operations, and implementing cryptographic code with secret dependent memory accesses (particularly SBoxes) such that the execution latency does not depend on the (secret) data being operated on.

RV32RV64MnemonicInstruction
xperm4 rd, rs1, rs2insns-xperm4
xperm8 rd, rs1, rs2insns-xperm8

11.9 Instructions (in alphabetical order)

The semantics of each instruction is expressed in a SAIL-like syntax.

11.9.1 add.uw

Synopsis Add unsigned word

Mnemonic add.uw rd, rs1, rs2

Pseudoinstructions zext.w rd, rs1 → add.uw rd, rs1, zero

Encoding

bb0029fd7e39b197974c3d9d0df6edfd

Description This instruction performs an XLEN-wide addition between rs2 and the zero-extended least-significant word of rs1.

Operation

let base = X(rs2);
let index = EXTZ(X(rs1)[31..0]);

X(rd) = base + index;

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.2 andn

Synopsis AND with inverted operand

Mnemonic andn rd, rs1, rs2

Encoding

e3cf592198f487b07f3600c5d06ac314

Description This instruction performs the bitwise logical AND operation between rs1 and the bitwise inversion of rs2.

Operation

X(rd) = X(rs1) & ~X(rs2);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified
Zbkb (zbkb)v1.0Ratified

11.9.3 bclr

Synopsis Single-Bit Clear (Register)

Mnemonic bclr rd, rs1, rs2

Encoding

a7ad2cd425c13bda5aef215191588c69

Description This instruction returns rs1 with a single bit cleared at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Operation

let index = X(rs2) & (XLEN - 1);
X(rd) = X(rs1) & ~(1 \<\< index)

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.4 bclri

Synopsis Single-Bit Clear (Immediate)

Mnemonic bclri rd, rs1, shamt

Encoding (RV32)

9704700d7e7b01bf676b9f131c094171

Encoding (RV64)

5cee792a932bf6b1a0787d4588d51ed1

Description This instruction returns rs1 with a single bit cleared 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.

Operation

let index = shamt & (XLEN - 1);
X(rd) = X(rs1) & ~(1 \<\< index)

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.5 bext

Synopsis Single-Bit Extract (Register)

Mnemonic bext rd, rs1, rs2

Encoding

0b44fd2dfac85d058162f3ff088cea8f

Description This instruction returns a single bit extracted from rs1 at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Operation

let index = X(rs2) & (XLEN - 1);
X(rd) = (X(rs1) >> index) & 1;

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.6 bexti

Synopsis Single-Bit Extract (Immediate)

Mnemonic bexti rd, rs1, shamt

Encoding (RV32)

3e448bb9acd2fb547a3b625da604e8e2

Encoding (RV64)

19725c39b232f49d0073a2e0ba85eaa5

Description This instruction returns a single bit extracted from rs1 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.

Operation

let index = shamt & (XLEN - 1);
X(rd) = (X(rs1) >> index) & 1;

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.7 binv

Synopsis Single-Bit Invert (Register)

Mnemonic binv rd, rs1, rs2

Encoding

82493bf5b4f34ed37da229e77a2b51a2

Description This instruction returns rs1 with a single bit inverted at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Operation

let index = X(rs2) & (XLEN - 1);
X(rd) = X(rs1) ^ (1 \<\< index)

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.8 binvi

Synopsis Single-Bit Invert (Immediate)

Mnemonic binvi rd, rs1, shamt

Encoding (RV32)

957e7bf73f1359580c17d7e4a87092c8

Encoding (RV64)

b8314cfb59713b8ae11ae3ad247836a2

Description This instruction returns rs1 with a single bit inverted 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.

Operation

let index = shamt & (XLEN - 1);
X(rd) = X(rs1) ^ (1 \<\< index)

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.9 bset

Synopsis Single-Bit Set (Register)

Mnemonic bset rd, rs1,rs2

Encoding

ed5e5e0105160a9a76f56c69cc528327

Description 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.

Operation

let index = X(rs2) & (XLEN - 1);
X(rd) = X(rs1) | (1 \<\< index)

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.10 bseti

Synopsis Single-Bit Set (Immediate)

Mnemonic bseti rd, rs1,shamt

Encoding (RV32)

8c918cfece377bd754a5b706a7606909

Encoding (RV64)

68ba6946c0d4b9165bd43d0fc355fef4

Description 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.

Operation

let index = shamt & (XLEN - 1);
X(rd) = X(rs1) | (1 \<\< index)

Included in

ExtensionMinimum versionLifecycle state
Zbs (zbs)v1.0Ratified

11.9.11 clmul

Synopsis Carry-less multiply (low-part)

Mnemonic clmul rd, rs1, rs2

Encoding

7cb5d90602c72ed961479f4ba3ac0ec8

Description clmul produces the lower half of the 2·XLEN carry-less product.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);
let output : xlenbits = 0;

foreach (i from 0 to (xlen - 1) by 1) {
output = if ((rs2_val >> i) & 1)
then output ^ (rs1_val \<\< i);
else output;
}

X[rd] = output

Included in

ExtensionMinimum versionLifecycle state
Zbc (zbc)v1.0Ratified
Zbkc (zbkc)v1.0Ratified

11.9.12 clmulh

Synopsis Carry-less multiply (high-part)

Mnemonic clmulh rd, rs1, rs2

Encoding

a742ffb7cdeed8899b26a1697d16c40b

Description clmulh produces the upper half of the 2·XLEN carry-less product.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);
let output : xlenbits = 0;

foreach (i from 1 to xlen by 1) {
output = if ((rs2_val >> i) & 1)
then output ^ (rs1_val >> (xlen - i));
else output;
}

X[rd] = output

Included in

ExtensionMinimum versionLifecycle state
Zbc (zbc)v1.0Ratified
Zbkc (zbkc)v1.0Ratified

11.9.13 clmulr

Synopsis Carry-less multiply (reversed)

Mnemonic clmulr rd, rs1, rs2

Encoding

186e584620f8a249028aaa4e5faed0c0

Description clmulr produces bits 2·XLEN−2:XLEN-1 of the 2·XLEN carry-less product.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);
let output : xlenbits = 0;

foreach (i from 0 to (xlen - 1) by 1) {
output = if ((rs2_val >> i) & 1)
then output ^ (rs1_val >> (xlen - i - 1));
else output;
}

X[rd] = output
note

The clmulr instruction is used to accelerate CRC calculations. The r in the instruction’s mnemonic stands for reversed, as the instruction is equivalent to bit-reversing the inputs, performing a clmul, then bit-reversing the output.

Included in

ExtensionMinimum versionLifecycle state
Zbc (zbc)v1.0Ratified

11.9.14 clz

Synopsis Count leading zero bits

Mnemonic clz rd, rs

Encoding

9780ec02cbc07bb312006a0566d581d6

Description This instruction counts the number of 0’s before the first 1, starting at the most-significant bit (i.e., XLEN-1) and progressing to bit 0. Accordingly, if the input is 0, the output is XLEN, and if the most-significant bit of the input is a 1, the output is 0.

Operation

val HighestSetBit : forall ('N : Int), 'N >= 0. bits('N) -> int

function HighestSetBit x = {
foreach (i from (xlen - 1) to 0 by 1 in dec)
if [x[i]] == 0b1 then return(i) else ();
return -1;
}

let rs = X(rs);
X[rd] = (xlen - 1) - HighestSetBit(rs);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.15 clzw

Synopsis Count leading zero bits in word

Mnemonic clzw rd, rs

Encoding

f2d2f1bd305b6f2d190375343eaec3b2

Description This instruction counts the number of 0’s before the first 1 starting at bit 31 and progressing to bit 0. Accordingly, if the least-significant word is 0, the output is 32, and if the most-significant bit of the word (i.e., bit 31) is a 1, the output is 0.

Operation

val HighestSetBit32 : forall ('N : Int), 'N >= 0. bits('N) -> int

function HighestSetBit32 x = {
foreach (i from 31 to 0 by 1 in dec)
if [x[i]] == 0b1 then return(i) else ();
return -1;
}

let rs = X(rs);
X[rd] = 31 - HighestSetBit(rs);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.16 cpop

Synopsis Count set bits

Mnemonic cpop rd, rs

Encoding

0a38723781e6998df1e3e4e1e190653b

Description This instructions counts the number of 1’s (i.e., set bits) in the source register.

Operation

let bitcount = 0;
let rs = X(rs);

foreach (i from 0 to (xlen - 1) in inc)
if rs[i] == 0b1 then bitcount = bitcount + 1 else ();

X[rd] = bitcount
note

This operation is known as population count, popcount, sideways sum, bit summation, or Hamming weight.

The GCC builtin function __builtin_popcount (unsigned int x) is implemented by cpop on RV32 and by cpopw on RV64. The GCC builtin function __builtin_popcountl (unsigned long x) for LP64 is implemented by cpop on RV64.

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.17 cpopw

Synopsis Count set bits in word

Mnemonic cpopw rd, rs

Encoding

da92c2dc03f2f7a8e89638d9eedc3857

Description This instructions counts the number of 1’s (i.e., set bits) in the least-significant word of the source register.

Operation

let bitcount = 0;
let val = X(rs);

foreach (i from 0 to 31 in inc)
if val[i] == 0b1 then bitcount = bitcount + 1 else ();

X[rd] = bitcount

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.18 ctz

Synopsis Count trailing zeros

Mnemonic ctz rd, rs

Encoding

30085d39c338bd8c32db553158164539

Description This instruction counts the number of 0’s before the first 1, starting at the least-significant bit (i.e., 0) and progressing to the most-significant bit (i.e., XLEN-1). Accordingly, if the input is 0, the output is XLEN, and if the least-significant bit of the input is a 1, the output is 0.

Operation

val LowestSetBit : forall ('N : Int), 'N >= 0. bits('N) -> int

function LowestSetBit x = {
foreach (i from 0 to (xlen - 1) by 1 in dec)
if [x[i]] == 0b1 then return(i) else ();
return xlen;
}

let rs = X(rs);
X[rd] = LowestSetBit(rs);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.19 ctzw

Synopsis Count trailing zero bits in word

Mnemonic ctzw rd, rs

Encoding

941649cd73c18b5bdce6ce9a6a2a32bd

Description This instruction counts the number of 0’s before the first 1, starting at the least-significant bit (i.e., 0) and progressing to the most-significant bit of the least-significant word (i.e., 31). Accordingly, if the least-significant word is 0, the output is 32, and if the least-significant bit of the input is a 1, the output is 0.

Operation

val LowestSetBit32 : forall ('N : Int), 'N >= 0. bits('N) -> int

function LowestSetBit32 x = {
foreach (i from 0 to 31 by 1 in dec)
if [x[i]] == 0b1 then return(i) else ();
return 32;
}

let rs = X(rs);
X[rd] = LowestSetBit32(rs);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.20 max

Synopsis Maximum

Mnemonic max rd, rs1, rs2

Encoding

d582d9453824479609c59dab164aa96a

Description This instruction returns the larger of two signed integers.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);

let result = if rs1_val \<_s rs2_val
then rs2_val
else rs1_val;

X(rd) = result;
note

Calculating the absolute value of a signed integer can be performed using the following sequence: neg rD,rS followed by max rD,rS,rD. When using this common sequence, it is suggested that they are scheduled with no intervening instructions so that implementations that are so optimized can fuse them together.

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.21 maxu

Synopsis Unsigned maximum

Mnemonic maxu rd, rs1, rs2

Encoding

393bf583f199d59c44063f06b0b22824

Description This instruction returns the larger of two unsigned integers.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);

let result = if rs1_val \<_u rs2_val
then rs2_val
else rs1_val;

X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.22 min

Synopsis Minimum

Mnemonic min rd, rs1, rs2

Encoding

078cf2c656ecd1925bb02a2c49183848

Description This instruction returns the smaller of two signed integers.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);

let result = if rs1_val \<_s rs2_val
then rs1_val
else rs2_val;

X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.23 minu

Synopsis Unsigned minimum

Mnemonic minu rd, rs1, rs2

Encoding

e87c77faa085fe1fffce46837a2c7089

Description This instruction returns the smaller of two unsigned integers.

Operation

let rs1_val = X(rs1);
let rs2_val = X(rs2);

let result = if rs1_val \<_u rs2_val
then rs1_val
else rs2_val;

X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.24 orc.b

Synopsis Bitwise OR-Combine, byte granule

Mnemonic orc.b rd, rs

Encoding

9f737b38721605b3fd354744b38d2797

Description Combines the bits within each byte using bitwise logical OR. This sets the bits of each byte in the result rd to all zeros if no bit within the respective byte of rs is set, or to all ones if any bit within the respective byte of rs is set.

Operation

let input = X(rs);
let output : xlenbits = 0;

foreach (i from 0 to (xlen - 8) by 8) {
output[(i + 7)..i] = if input[(i + 7)..i] == 0
then 0b00000000
else 0b11111111;
}

X[rd] = output;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified

11.9.25 orn

Synopsis OR with inverted operand

Mnemonic orn rd, rs1, rs2

Encoding

3bd18ecde333f2cd8a73549851e8022e

Description This instruction performs the bitwise logical OR operation between rs1 and the bitwise inversion of rs2.

Operation

X(rd) = X(rs1) | ~X(rs2);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified
Zbkb (zbkb)v1.0Ratified

11.9.26 pack

Synopsis Pack the low halves of rs1 and rs2 into rd.

Mnemonic pack rd, rs1, rs2

Encoding

7fa85755c34dc122ea4672b268b286ef

Description The pack instruction packs the XLEN/2-bit lower halves of rs1 and rs2 into rd, with rs1 in the lower half and rs2 in the upper half.

Operation

let lo_half : bits(xlen/2) = X(rs1)[xlen/2-1..0];
let hi_half : bits(xlen/2) = X(rs2)[xlen/2-1..0];
X(rd) = EXTZ(hi_half @ lo_half);

Included in

ExtensionMinimum versionLifecycle state
Zbkb (zbkb)v1.0Ratified
note

For RV32, the pack instruction with rs2=x0 is the zext.h instruction. Hence, for RV32, any extension that contains the pack instruction also contains the zext.h instruction (but not necessarily the c.zext.h instruction, which is only guaranteed to exist if both the Zcb and Zbb extensions are implemented).

11.9.27 packh

Synopsis Pack the low bytes of rs1 and rs2 into rd.

Mnemonic packh rd, rs1, rs2

Encoding

05917e419e9c78603bb46472d55f9702

Description The packh instruction packs the least-significant bytes of rs1 and rs2 into the 16 least-significant bits of rd, zero extending the rest of rd.

Operation

let lo_half : bits(8) = X(rs1)[7..0];
let hi_half : bits(8) = X(rs2)[7..0];
X(rd) = EXTZ(hi_half @ lo_half);

Included in

ExtensionMinimum versionLifecycle state
Zbkb (zbkb)v1.0Ratified

11.9.28 packw

Synopsis Pack the low 16-bits of rs1 and rs2 into rd on RV64.

Mnemonic packw rd, rs1, rs2

Encoding

dea689a62b78a7a98df01155920b4dcf

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. This instruction only exists on RV64 based systems.

Operation

let lo_half : bits(16) = X(rs1)[15..0];
let hi_half : bits(16) = X(rs2)[15..0];
X(rd) = EXTS(hi_half @ lo_half);

Included in

ExtensionMinimum versionLifecycle state
Zbkb (zbkb)v1.0Ratified
note

For RV64, the packw instruction with rs2=x0 is the zext.h instruction. Hence, for RV64, any extension that contains the packw instruction also contains the zext.h instruction (but not necessarily the c.zext.h instruction, which is only guaranteed to exist if both the Zcb and Zbb extensions are implemented).

11.9.29 rev8

Synopsis Byte-reverse register

Mnemonic rev8 rd, rs

Encoding (RV32)

ef131173967d35b5f3163d3d295f5fcc

Encoding (RV64)

af732656994c0c8fbdf56f99e7e24829

Description This instruction reverses the order of the bytes in rs.

Operation

let input = X(rs);
let output : xlenbits = 0;
let j = xlen - 1;

foreach (i from 0 to (xlen - 8) by 8) {
output[i..(i + 7)] = input[(j - 7)..j];
j = j - 8;
}

X[rd] = output
note

The rev8 mnemonic corresponds to different instruction encodings in RV32 and RV64.

note

The byte-reverse operation is only available for the full register width. To emulate word-sized and halfword-sized byte-reversal, perform a rev8 rd,rs followed by a srai rd,rd,K, where K is XLEN-32 and XLEN-16, respectively.

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)v1.0Ratified
Zbkb (zbkb)v1.0Ratified

11.9.30 brev8

Synopsis Reverse the bits in each byte of a source register.

Mnemonic brev8 rd, rs

Encoding

7f694100e5d2a0a4a34c7d89d148aa54

Description This instruction reverses the order of the bits in every byte of a register.

Operation

result : xlenbits = EXTZ(0b0);
foreach (i from 0 to sizeof(xlen) by 8) {
result[i+7..i] = reverse_bits_in_byte(X(rs1)[i+7..i]);
};
X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbkb (zbkb)v1.0Ratified

11.9.31 rol

Synopsis Rotate Left (Register)

Mnemonic rol rd, rs1, rs2

Encoding

580fc9cd3e1862df44bcea50dbc5ff2d

Description This instruction performs a rotate left of rs1 by the amount in least-significant log2(XLEN) bits of rs2.

Operation

let shamt = if xlen == 32
then X(rs2)[4..0]
else X(rs2)[5..0];
let result = (X(rs1) \<\< shamt) | (X(rs1) >> (xlen - shamt));

X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.32 rolw

Synopsis Rotate Left Word (Register)

Mnemonic rolw rd, rs1, rs2

Encoding

b4c99cff484b2c027fb98885e44895e4

Description This instruction performs a rotate left on the least-significant word of rs1 by the amount in least-significant 5 bits of rs2. The resulting word value is sign-extended by copying bit 31 to all of the more-significant bits.

Operation

let rs1 = EXTZ(X(rs1)[31..0])
let shamt = X(rs2)[4..0];
let result = (rs1 \<\< shamt) | (rs1 >> (32 - shamt));
X(rd) = EXTS(result[31..0]);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.33 ror

Synopsis Rotate Right

Mnemonic ror rd, rs1, rs2

Encoding

d7ab99180b2745052655cf336067af74

Description This instruction performs a rotate right of rs1 by the amount in least-significant log2(XLEN) bits of rs2.

Operation

let shamt = if xlen == 32
then X(rs2)[4..0]
else X(rs2)[5..0];
let result = (X(rs1) >> shamt) | (X(rs1) \<\< (xlen - shamt));

X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.34 rori

Synopsis Rotate Right (Immediate)

Mnemonic rori rd, rs1, shamt

Encoding (RV32)

496f252d8f24f02f32ed94e2c67b3c21

Encoding (RV64)

22aeb058c66e1020732bdf0f5c621412

Description This instruction performs a rotate right of rs1 by the amount in the least-significant log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved.

Operation

let shamt = if xlen == 32
then shamt[4..0]
else shamt[5..0];
let result = (X(rs1) >> shamt) | (X(rs1) \<\< (xlen - shamt));

X(rd) = result;

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.35 roriw

Synopsis Rotate Right Word by Immediate

Mnemonic roriw rd, rs1, shamt

Encoding

7a5fe26872f7a9eaec2539ba23442a35

Description This instruction performs a rotate right on the least-significant word of rs1 by the amount in the least-significant log2(XLEN) bits of shamt. The resulting word value is sign-extended by copying bit 31 to all of the more-significant bits.

Operation

let rs1_data = EXTZ(X(rs1)[31..0];
let result = (rs1_data >> shamt) | (rs1_data \<\< (32 - shamt));
X(rd) = EXTS(result[31..0]);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.36 rorw

Synopsis Rotate Right Word (Register)

Mnemonic rorw rd, rs1, rs2

Encoding

508dfa18cb434b4f770a597070a5f8b1

Description This instruction performs a rotate right on the least-significant word of rs1 by the amount in least-significant 5 bits of rs2. The resultant word is sign-extended by copying bit 31 to all of the more-significant bits.

Operation

let rs1 = EXTZ(X(rs1)[31..0])
let shamt = X(rs2)[4..0];
let result = (rs1 >> shamt) | (rs1 \<\< (32 - shamt));
X(rd) = EXTS(result);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.37 sext.b

Synopsis Sign-extend byte

Mnemonic sext.b rd, rs

Encoding

e9db6d5c0c20ba1c046b4a697b7dd9fa

Description This instruction sign-extends the least-significant byte in the source to XLEN by copying the most-significant bit in the byte (i.e., bit 7) to all of the more-significant bits.

Operation

X(rd) = EXTS(X(rs)[7..0]);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified

11.9.38 sext.h

Synopsis Sign-extend halfword

Mnemonic sext.h rd, rs

Encoding

699991b6c65f1c7110cb44eb20cb9291

Description This instruction sign-extends the least-significant halfword in rs to XLEN by copying the most-significant bit in the halfword (i.e., bit 15) to all of the more-significant bits.

Operation

X(rd) = EXTS(X(rs)[15..0]);

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified

11.9.39 sh1add

Synopsis Shift left by 1 and add

Mnemonic sh1add rd, rs1, rs2

Encoding

779c762199734a24471a26a668346cbd

Description This instruction shifts rs1 to the left by 1 bit and adds it to rs2.

Operation

X(rd) = X(rs2) + (X(rs1) \<\< 1);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.40 sh1add.uw

Synopsis Shift unsigned word left by 1 and add

Mnemonic sh1add.uw rd, rs1, rs2

Encoding

fb2dec187fb19427cca440612cab3a47

Description This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 1 place.

Operation

let base = X(rs2);
let index = EXTZ(X(rs1)[31..0]);

X(rd) = base + (index \<\< 1);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.41 sh2add

Synopsis Shift left by 2 and add

Mnemonic sh2add rd, rs1, rs2

Encoding

19b7d23982310cb63fe603f2ab5cbdf8

Description This instruction shifts rs1 to the left by 2 places and adds it to rs2.

Operation

X(rd) = X(rs2) + (X(rs1) \<\< 2);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.42 sh2add.uw

Synopsis Shift unsigned word left by 2 and add

Mnemonic sh2add.uw rd, rs1, rs2

Encoding

2b9986d7757c2f83c5382d5ba9e3ffd9

Description This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 2 places.

Operation

let base = X(rs2);
let index = EXTZ(X(rs1)[31..0]);

X(rd) = base + (index \<\< 2);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.43 sh3add

Synopsis Shift left by 3 and add

Mnemonic sh3add rd, rs1, rs2

Encoding

ecf88a9fe09a4b3f7734d4d8ed2372da

Description This instruction shifts rs1 to the left by 3 places and adds it to rs2.

Operation

X(rd) = X(rs2) + (X(rs1) \<\< 3);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.44 sh3add.uw

Synopsis Shift unsigned word left by 3 and add

Mnemonic sh3add.uw rd, rs1, rs2

Encoding

4e0d0179e04965dff0205a3c383a6ada

Description This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 3 places.

Operation

let base = X(rs2);
let index = EXTZ(X(rs1)[31..0]);

X(rd) = base + (index \<\< 3);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified

11.9.45 slli.uw

Synopsis Shift-left unsigned word (Immediate)

Mnemonic slli.uw rd, rs1, shamt

Encoding

78f1ec7de5f6a554d76eb0ad67eb4826

Description This instruction takes the least-significant word of rs1, zero-extends it, and shifts it left by the immediate.

Operation

X(rd) = (EXTZ(X(rs)[31..0]) \<\< shamt);

Included in

ExtensionMinimum versionLifecycle state
Zba (zba)0.93Ratified
note

This instruction is the same as slli with zext.w performed on rs1 before shifting.

11.9.46 unzip

Synopsis Place odd and even bits of the source register into upper and lower halves of the destination register, respectively.

Mnemonic unzip rd, rs

Encoding

26288253d518ddedf6ba6e8bcc1f9475

Description This instruction scatters all of the odd and even bits of a source word into the high and low halves of a destination word. It is the inverse of the zip instruction. This instruction is available only on RV32.

Operation

foreach (i from 0 to xlen/2-1) {
X(rd)[i] = X(rs1)[2*i]
X(rd)[i+xlen/2] = X(rs1)[2*i+1]
}
note

This instruction is useful for implementing the SHA3 cryptographic hash function on a 32-bit architecture, as it implements the bit-interleaving operation used to speed up the 64-bit rotations directly.

Included in

ExtensionMinimum versionLifecycle state
Zbkb (zbkb) (RV32)v1.0Ratified

11.9.47 xnor

Synopsis Exclusive NOR

Mnemonic xnor rd, rs1, rs2

Encoding

2aac771baf69437da5eab9db4679fd23

Description This instruction performs the bit-wise exclusive-NOR operation on rs1 and rs2.

Operation

X(rd) = ~(X(rs1) ^ X(rs2));

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified
Zbkb (zbkb)v1.0Ratified

11.9.48 xperm8

Synopsis Byte-wise lookup of indices into a vector in registers.

Mnemonic xperm8 rd, rs1, rs2

Encoding

e2e209a9db2f3c6739407d6a8990aef3

Description The xperm8 instruction operates on bytes. The rs1 register contains a vector of XLEN/8 8-bit elements. The rs2 register contains a vector of XLEN/8 8-bit indexes. The result is each element in rs2 replaced by the indexed element in rs1, or zero if the index into rs2 is out of bounds.

Operation

val xperm8_lookup : (bits(8), xlenbits) -> bits(8)
function xperm8_lookup (idx, lut) = {
(lut >> (idx @ 0b000))[7..0]
}

function clause execute ( XPERM8 (rs2,rs1,rd)) = {
result : xlenbits = EXTZ(0b0);
foreach(i from 0 to xlen by 8) {
result[i+7..i] = xperm8_lookup(X(rs2)[i+7..i], X(rs1));
};
X(rd) = result;
RETIRE_SUCCESS
}

Included in

ExtensionMinimum versionLifecycle state
Zbkx (zbkx)v1.0Ratified

11.9.49 xperm4

Synopsis Nibble-wise lookup of indices into a vector.

Mnemonic xperm4 rd, rs1, rs2

Encoding

164eee2cea9c11926307851f829c0400

Description The xperm4 instruction operates on nibbles. The rs1 register contains a vector of XLEN/4 4-bit elements. The rs2 register contains a vector of XLEN/4 4-bit indexes. The result is each element in rs2 replaced by the indexed element in rs1, or zero if the index into rs2 is out of bounds.

Operation

val xperm4_lookup : (bits(4), xlenbits) -> bits(4)
function xperm4_lookup (idx, lut) = {
(lut >> (idx @ 0b00))[3..0]
}

function clause execute ( XPERM4 (rs2,rs1,rd)) = {
result : xlenbits = EXTZ(0b0);
foreach(i from 0 to xlen by 4) {
result[i+3..i] = xperm4_lookup(X(rs2)[i+3..i], X(rs1));
};
X(rd) = result;
RETIRE_SUCCESS
}

Included in

ExtensionMinimum versionLifecycle state
Zbkx (zbkx)v1.0Ratified

11.9.50 zext.h

Synopsis Zero-extend halfword

Mnemonic zext.h rd, rs

Encoding (RV32)

70dda6da2c595d7cd2def9b3c31eb20f

Encoding (RV64)

3c9ea313023290daac2380fa7eab3a70

Description This instruction zero-extends the least-significant halfword of the source to XLEN by inserting 0’s into all of the bits more significant than 15.

Operation

X(rd) = EXTZ(X(rs)[15..0]);
note

The zext.h mnemonic corresponds to different instruction encodings in RV32 and RV64.

Included in

ExtensionMinimum versionLifecycle state
Zbb (zbb)0.93Ratified

11.9.51 zip

Synopsis Interleave upper and lower halves of the source register into odd and even bits of the destination register, respectively.

Mnemonic zip rd, rs

Encoding

3b32fab57e6c34675e25fcdbf949f068

Description This instruction gathers bits from the high and low halves of the source word into odd/even bit positions in the destination word. It is the inverse of the unzip instruction. This instruction is available only on RV32.

Operation

foreach (i from 0 to xlen/2-1) {
X(rd)[2*i] = X(rs1)[i]
X(rd)[2*i+1] = X(rs1)[i+xlen/2]
}
note

This instruction is useful for implementing the SHA3 cryptographic hash function on a 32-bit architecture, as it implements the bit-interleaving operation used to speed up the 64-bit rotations directly.

Included in

ExtensionMinimum versionLifecycle state
Zbkb (zbkb) (RV32)v1.0Ratified