RV32 Reference 2
RV32 Reference 2
This chapter describes version 2.0 of the RV32I base integer instruction set.
RV32I was designed to be sufficient to form a compiler target and to support modern operating
system environments. The ISA was also designed to reduce the hardware required in a minimal
implementation. RV32I contains 40 unique instructions, though a simple implementation might
cover the ECALL/EBREAK instructions with a single SYSTEM hardware instruction that al-
ways traps and might be able to implement the FENCE instruction as a NOP, reducing base
instruction count to 38 total. RV32I can emulate almost any other ISA extension (except the A
extension, which requires additional hardware support for atomicity).
In practice, a hardware implementation including the machine-mode privileged architecture
will also require the 6 CSR instructions.
Subsets of the base integer ISA might be useful for pedagogical purposes, but the base has
been defined such that there should be little incentive to subset a real hardware implementation
beyond omitting support for misaligned memory accesses and treating all SYSTEM instructions
as a single trap.
The standard RISC-V assembly language syntax is documented in the Assembly Programmer’s
Manual [1].
Most of the commentary for RV32I also applies to the RV64I base.
Figure 2.1 shows the unprivileged state for the base integer ISA. For RV32I, the 32 x registers
are each 32 bits wide, i.e., XLEN=32. Register x0 is hardwired with all bits equal to 0. General
purpose registers x1–x31 hold values that various instructions interpret as a collection of Boolean
values, or as two’s complement signed binary integers or unsigned binary integers.
13
14 Volume I: RISC-V Unprivileged ISA V20191214-draft
There is one additional unprivileged register: the program counter pc holds the address of the
current instruction.
XLEN-1 0
x0 / zero
x1
x2
x3
x4
x5
x6
x7
x8
x9
x10
x11
x12
x13
x14
x15
x16
x17
x18
x19
x20
x21
x22
x23
x24
x25
x26
x27
x28
x29
x30
x31
XLEN
XLEN-1 0
pc
XLEN
There is no dedicated stack pointer or subroutine return address link register in the Base Integer
ISA; the instruction encoding allows any x register to be used for these purposes. However, the
standard software calling convention uses register x1 to hold the return address for a call, with
register x5 available as an alternate link register. The standard calling convention uses register
x2 as the stack pointer.
Hardware might choose to accelerate function calls and returns that use x1 or x5. See the
descriptions of the JAL and JALR instructions.
The optional compressed 16-bit instruction format is designed around the assumption that
x1 is the return address register and x2 is the stack pointer. Software using other conventions
will operate correctly but may have greater code size.
Volume I: RISC-V Unprivileged ISA V20191214-draft 15
The number of available architectural registers can have large impacts on code size, performance,
and energy consumption. Although 16 registers would arguably be sufficient for an integer ISA
running compiled code, it is impossible to encode a complete ISA with 16 registers in 16-bit
instructions using a 3-address format. Although a 2-address format would be possible, it would
increase instruction count and lower efficiency. We wanted to avoid intermediate instruction
sizes (such as Xtensa’s 24-bit instructions) to simplify base hardware implementations, and once
a 32-bit instruction size was adopted, it was straightforward to support 32 integer registers. A
larger number of integer registers also helps performance on high-performance code, where there
can be extensive use of loop unrolling, software pipelining, and cache tiling.
For these reasons, we chose a conventional size of 32 integer registers for the base ISA. Dy-
namic register usage tends to be dominated by a few frequently accessed registers, and regfile im-
plementations can be optimized to reduce access energy for the frequently accessed registers [21].
The optional compressed 16-bit instruction format mostly only accesses 8 registers and hence can
provide a dense instruction encoding, while additional instruction-set extensions could support
a much larger register space (either flat or hierarchical) if desired.
For resource-constrained embedded applications, we have defined the RV32E subset, which
only has 16 registers (Chapter 4).
In the base RV32I ISA, there are four core instruction formats (R/I/S/U), as shown in Figure 2.2.
All are a fixed 32 bits in length and must be aligned on a four-byte boundary in memory. An
instruction-address-misaligned exception is generated on a taken branch or unconditional jump
if the target address is not four-byte aligned. This exception is reported on the branch or jump
instruction, not on the target instruction. No instruction-address-misaligned exception is generated
for a conditional branch that is not taken.
The alignment constraint for base ISA instructions is relaxed to a two-byte boundary when
instruction extensions with 16-bit lengths or other odd multiples of 16-bit lengths are added
(i.e., IALIGN=16).
Instruction-address-misaligned exceptions are reported on the branch or jump that would
cause instruction misalignment to help debugging, and to simplify hardware design for systems
with IALIGN=32, where these are the only places where misalignment can occur.
Some platforms may require that opcodes reserved for standard use raise an illegal-instruction
exception. Other platforms may permit reserved opcode space be used for non-conforming exten-
sions.
The RISC-V ISA keeps the source (rs1 and rs2) and destination (rd) registers at the same position
in all formats to simplify decoding. Except for the 5-bit immediates used in CSR instructions
(Chapter 9), immediates are always sign-extended, and are generally packed towards the leftmost
available bits in the instruction and have been allocated to reduce hardware complexity. In partic-
ular, the sign bit for all immediates is always in bit 31 of the instruction to speed sign-extension
circuitry.
16 Volume I: RISC-V Unprivileged ISA V20191214-draft
31 25 24 20 19 15 14 12 11 7 6 0
funct7 rs2 rs1 funct3 rd opcode R-type
Figure 2.2: RISC-V base instruction formats. Each immediate subfield is labeled with the bit
position (imm[x ]) in the immediate value being produced, rather than the bit position within the
instruction’s immediate field as is usually done.
Decoding register specifiers is usually on the critical paths in implementations, and so the in-
struction format was chosen to keep all register specifiers at the same position in all formats at
the expense of having to move immediate bits across formats (a property shared with RISC-IV
aka. SPUR [12]).
In practice, most immediates are either small or require all XLEN bits. We chose an asym-
metric immediate split (12 bits in regular instructions plus a special load-upper-immediate in-
struction with 20 bits) to increase the opcode space available for regular instructions.
Immediates are sign-extended because we did not observe a benefit to using zero-extension
for some immediates as in the MIPS ISA and wanted to keep the ISA as simple as possible.
There are a further two variants of the instruction formats (B/J) based on the handling of imme-
diates, as shown in Figure 2.3.
31 30 25 24 21 20 19 15 14 12 11 8 7 6 0
funct7 rs2 rs1 funct3 rd opcode R-type
The only di↵erence between the S and B formats is that the 12-bit immediate field is used to encode
branch o↵sets in multiples of 2 in the B format. Instead of shifting all bits in the instruction-encoded
Volume I: RISC-V Unprivileged ISA V20191214-draft 17
immediate left by one in hardware as is conventionally done, the middle bits (imm[10:1]) and sign
bit stay in fixed positions, while the lowest bit in S format (inst[7]) encodes a high-order bit in B
format.
Similarly, the only di↵erence between the U and J formats is that the 20-bit immediate is shifted
left by 12 bits to form U immediates and by 1 bit to form J immediates. The location of instruction
bits in the U and J format immediates is chosen to maximize overlap with the other formats and
with each other.
Figure 2.4 shows the immediates produced by each of the base instruction formats, and is labeled
to show which instruction bit (inst[y ]) produces each bit of the immediate value.
31 30 20 19 12 11 10 5 4 1 0
— inst[31] — inst[30:25] inst[24:21] inst[20] I-immediate
Figure 2.4: Types of immediate produced by RISC-V instructions. The fields are labeled with the
instruction bits used to construct their value. Sign extension always uses inst[31].
Sign-extension is one of the most critical operations on immediates (particularly for XLEN>32),
and in RISC-V the sign bit for all immediates is always held in bit 31 of the instruction to allow
sign-extension to proceed in parallel with instruction decoding.
Although more complex implementations might have separate adders for branch and jump
calculations and so would not benefit from keeping the location of immediate bits constant across
types of instruction, we wanted to reduce the hardware cost of the simplest implementations. By
rotating bits in the instruction encoding of B and J immediates instead of using dynamic hard-
ware muxes to multiply the immediate by 2, we reduce instruction signal fanout and immediate
mux costs by around a factor of 2. The scrambled immediate encoding will add negligible time
to static or ahead-of-time compilation. For dynamic generation of instructions, there is some
small additional overhead, but the most common short forward branches have straightforward
immediate encodings.
Most integer computational instructions operate on XLEN bits of values held in the integer register
file. Integer computational instructions are either encoded as register-immediate operations using
the I-type format or as register-register operations using the R-type format. The destination is
register rd for both register-immediate and register-register instructions. No integer computational
instructions cause arithmetic exceptions.
18 Volume I: RISC-V Unprivileged ISA V20191214-draft
We did not include special instruction-set support for overflow checks on integer arithmetic
operations in the base instruction set, as many overflow checks can be cheaply implemented using
RISC-V branches. Overflow checking for unsigned addition requires only a single additional
branch instruction after the addition: add t0, t1, t2; bltu t0, t1, overflow.
For signed addition, if one operand’s sign is known, overflow checking requires only a single
branch after the addition: addi t0, t1, +imm; blt t0, t1, overflow. This covers the
common case of addition with an immediate operand.
For general signed addition, three additional instructions after the addition are required,
leveraging the observation that the sum should be less than one of the operands if and only if the
other operand is negative.
add t0, t1, t2
slti t3, t2, 0
slt t4, t0, t1
bne t3, t4, overflow
In RV64I, checks of 32-bit signed additions can be optimized further by comparing the results of
ADD and ADDW on the operands.
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
12 5 3 5 7
I-immediate[11:0] src ADDI/SLTI[U] dest OP-IMM
I-immediate[11:0] src ANDI/ORI/XORI dest OP-IMM
ADDI adds the sign-extended 12-bit immediate to register rs1. Arithmetic overflow is ignored and
the result is simply the low XLEN bits of the result. ADDI rd, rs1, 0 is used to implement the MV
rd, rs1 assembler pseudoinstruction.
SLTI (set less than immediate) places the value 1 in register rd if register rs1 is less than the sign-
extended immediate when both are treated as signed numbers, else 0 is written to rd. SLTIU is
similar but compares the values as unsigned numbers (i.e., the immediate is first sign-extended to
XLEN bits then treated as an unsigned number). Note, SLTIU rd, rs1, 1 sets rd to 1 if rs1 equals
zero, otherwise sets rd to 0 (assembler pseudoinstruction SEQZ rd, rs).
ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and XOR on register rs1
and the sign-extended 12-bit immediate and place the result in rd. Note, XORI rd, rs1, -1 performs
a bitwise logical inversion of register rs1 (assembler pseudoinstruction NOT rd, rs).
31 25 24 20 19 15 14 12 11 7 6 0
imm[11:5] imm[4:0] rs1 funct3 rd opcode
7 5 5 3 5 7
0000000 shamt[4:0] src SLLI dest OP-IMM
0000000 shamt[4:0] src SRLI dest OP-IMM
0100000 shamt[4:0] src SRAI dest OP-IMM
Volume I: RISC-V Unprivileged ISA V20191214-draft 19
Shifts by a constant are encoded as a specialization of the I-type format. The operand to be shifted
is in rs1, and the shift amount is encoded in the lower 5 bits of the I-immediate field. The right
shift type is encoded in bit 30. SLLI is a logical left shift (zeros are shifted into the lower bits);
SRLI is a logical right shift (zeros are shifted into the upper bits); and SRAI is an arithmetic right
shift (the original sign bit is copied into the vacated upper bits).
31 12 11 7 6 0
imm[31:12] rd opcode
20 5 7
U-immediate[31:12] dest LUI
U-immediate[31:12] dest AUIPC
LUI (load upper immediate) is used to build 32-bit constants and uses the U-type format. LUI
places the 32-bit U-immediate value into the destination register rd, filling in the lowest 12 bits
with zeros.
AUIPC (add upper immediate to pc) is used to build pc-relative addresses and uses the U-type
format. AUIPC forms a 32-bit o↵set from the U-immediate, filling in the lowest 12 bits with zeros,
adds this o↵set to the address of the AUIPC instruction, then places the result in register rd.
The assembly syntax for lui and auipc does not represent the lower 12 bits of the U-immediate,
which are always zero.
The AUIPC instruction supports two-instruction sequences to access arbitrary o↵sets from
the PC for both control-flow transfers and data accesses. The combination of an AUIPC and
the 12-bit immediate in a JALR can transfer control to any 32-bit PC-relative address, while
an AUIPC plus the 12-bit immediate o↵set in regular load or store instructions can access any
32-bit PC-relative data address.
The current PC can be obtained by setting the U-immediate to 0. Although a JAL +4
instruction could also be used to obtain the local PC (of the instruction following the JAL),
it might cause pipeline breaks in simpler microarchitectures or pollute BTB structures in more
complex microarchitectures.
RV32I defines several arithmetic R-type operations. All operations read the rs1 and rs2 registers
as source operands and write the result into register rd. The funct7 and funct3 fields select the
type of operation.
31 25 24 20 19 15 14 12 11 7 6 0
funct7 rs2 rs1 funct3 rd opcode
7 5 5 3 5 7
0000000 src2 src1 ADD/SLT/SLTU dest OP
0000000 src2 src1 AND/OR/XOR dest OP
0000000 src2 src1 SLL/SRL dest OP
0100000 src2 src1 SUB/SRA dest OP
20 Volume I: RISC-V Unprivileged ISA V20191214-draft
ADD performs the addition of rs1 and rs2. SUB performs the subtraction of rs2 from rs1. Overflows
are ignored and the low XLEN bits of results are written to the destination rd. SLT and SLTU
perform signed and unsigned compares respectively, writing 1 to rd if rs1 < rs2, 0 otherwise. Note,
SLTU rd, x0, rs2 sets rd to 1 if rs2 is not equal to zero, otherwise sets rd to zero (assembler
pseudoinstruction SNEZ rd, rs). AND, OR, and XOR perform bitwise logical operations.
SLL, SRL, and SRA perform logical left, logical right, and arithmetic right shifts on the value in
register rs1 by the shift amount held in the lower 5 bits of register rs2.
NOP Instruction
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
12 5 3 5 7
0 0 ADDI 0 OP-IMM
The NOP instruction does not change any architecturally visible state, except for advancing the
pc and incrementing any applicable performance counters. NOP is encoded as ADDI x0, x0, 0.
NOPs can be used to align code segments to microarchitecturally significant address boundaries,
or to leave space for inline code modifications. Although there are many possible ways to encode
a NOP, we define a canonical NOP encoding to allow microarchitectural optimizations as well as
for more readable disassembly output. The other NOP encodings are made available for HINT
instructions (Section 2.9).
ADDI was chosen for the NOP encoding as this is most likely to take fewest resources to
execute across a range of systems (if not optimized away in decode). In particular, the instruction
only reads one register. Also, an ADDI functional unit is more likely to be available in a
superscalar design as adds are the most common operation. In particular, address-generation
functional units can execute ADDI using the same hardware needed for base+o↵set address
calculations, while register-register ADD or logical/shift operations require additional hardware.
RV32I provides two types of control transfer instructions: unconditional jumps and conditional
branches. Control transfer instructions in RV32I do not have architecturally visible delay slots.
Unconditional Jumps
The jump and link (JAL) instruction uses the J-type format, where the J-immediate encodes a
signed o↵set in multiples of 2 bytes. The o↵set is sign-extended and added to the address of the
jump instruction to form the jump target address. Jumps can therefore target a ±1 MiB range.
Volume I: RISC-V Unprivileged ISA V20191214-draft 21
JAL stores the address of the instruction following the jump (pc+4) into register rd. The standard
software calling convention uses x1 as the return address register and x5 as an alternate link register.
The alternate link register supports calling millicode routines (e.g., those to save and restore
registers in compressed code) while preserving the regular return address register. The register
x5 was chosen as the alternate link register as it maps to a temporary in the standard calling
convention, and has an encoding that is only one bit di↵erent than the regular link register.
Plain unconditional jumps (assembler pseudoinstruction J) are encoded as a JAL with rd=x0.
31 30 21 20 19 12 11 7 6 0
imm[20] imm[10:1] imm[11] imm[19:12] rd opcode
1 10 1 8 5 7
o↵set[20:1] dest JAL
The indirect jump instruction JALR (jump and link register) uses the I-type encoding. The target
address is obtained by adding the sign-extended 12-bit I-immediate to the register rs1, then setting
the least-significant bit of the result to zero. The address of the instruction following the jump
(pc+4) is written to register rd. Register x0 can be used as the destination if the result is not
required.
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
12 5 3 5 7
o↵set[11:0] base 0 dest JALR
The unconditional jump instructions all use PC-relative addressing to help support position-
independent code. The JALR instruction was defined to enable a two-instruction sequence to
jump anywhere in a 32-bit absolute address range. A LUI instruction can first load rs1 with the
upper 20 bits of a target address, then JALR can add in the lower bits. Similarly, AUIPC then
JALR can jump anywhere in a 32-bit pc-relative address range.
Note that the JALR instruction does not treat the 12-bit immediate as multiples of 2 bytes,
unlike the conditional branch instructions. This avoids one more immediate format in hardware.
In practice, most uses of JALR will have either a zero immediate or be paired with a LUI or
AUIPC, so the slight reduction in range is not significant.
Clearing the least-significant bit when calculating the JALR target address both simplifies
the hardware slightly and allows the low bit of function pointers to be used to store auxiliary
information. Although there is potentially a slight loss of error checking in this case, in practice
jumps to an incorrect instruction address will usually quickly raise an exception.
When used with a base rs1=x0, JALR can be used to implement a single instruction subrou-
tine call to the lowest 2 KiB or highest 2 KiB address region from anywhere in the address space,
which could be used to implement fast calls to a small runtime library. Alternatively, an ABI
could dedicate a general-purpose register to point to a library elsewhere in the address space.
The JAL and JALR instructions will generate an instruction-address-misaligned exception if the
target address is not aligned to a four-byte boundary.
Table 2.1: Return-address stack prediction hints encoded in the register operands of a JALR
instruction.
Some other ISAs added explicit hint bits to their indirect-jump instructions to guide return-
address stack manipulation. We use implicit hinting tied to register numbers and the calling
convention to reduce the encoding space used for these hints.
When two di↵erent link registers (x1 and x5) are given as rs1 and rd, then the RAS
is both popped and pushed to support coroutines. If rs1 and rd are the same link regis-
ter (either x1 or x5), the RAS is only pushed to enable macro-op fusion of the sequences:
lui ra, imm20; jalr ra, imm12(ra) and auipc ra, imm20; jalr ra, imm12(ra)
Conditional Branches
All branch instructions use the B-type instruction format. The 12-bit B-immediate encodes signed
o↵sets in multiples of 2 bytes. The o↵set is sign-extended and added to the address of the branch
instruction to give the target address. The conditional branch range is ±4 KiB.
31 30 25 24 20 19 15 14 12 11 8 7 6 0
imm[12] imm[10:5] rs2 rs1 funct3 imm[4:1] imm[11] opcode
1 6 5 5 3 4 1 7
o↵set[12|10:5] src2 src1 BEQ/BNE o↵set[11|4:1] BRANCH
o↵set[12|10:5] src2 src1 BLT[U] o↵set[11|4:1] BRANCH
o↵set[12|10:5] src2 src1 BGE[U] o↵set[11|4:1] BRANCH
Branch instructions compare two registers. BEQ and BNE take the branch if registers rs1 and rs2
are equal or unequal respectively. BLT and BLTU take the branch if rs1 is less than rs2, using
signed and unsigned comparison respectively. BGE and BGEU take the branch if rs1 is greater
than or equal to rs2, using signed and unsigned comparison respectively. Note, BGT, BGTU,
BLE, and BLEU can be synthesized by reversing the operands to BLT, BLTU, BGE, and BGEU,
respectively.
Signed array bounds may be checked with a single BLTU instruction, since any negative index
will compare greater than any nonnegative bound.
Volume I: RISC-V Unprivileged ISA V20191214-draft 23
Software should be optimized such that the sequential code path is the most common path, with
less-frequently taken code paths placed out of line. Software should also assume that backward
branches will be predicted taken and forward branches as not taken, at least the first time they are
encountered. Dynamic predictors should quickly learn any predictable branch behavior.
Unlike some other architectures, the RISC-V jump (JAL with rd=x0) instruction should always
be used for unconditional branches instead of a conditional branch instruction with an always-
true condition. RISC-V jumps are also PC-relative and support a much wider o↵set range than
branches, and will not pollute conditional-branch prediction tables.
The conditional branches were designed to include arithmetic comparison operations between two
registers (as also done in PA-RISC, Xtensa, and MIPS R6), rather than use condition codes
(x86, ARM, SPARC, PowerPC), or to only compare one register against zero (Alpha, MIPS),
or two registers only for equality (MIPS). This design was motivated by the observation that a
combined compare-and-branch instruction fits into a regular pipeline, avoids additional condition
code state or use of a temporary register, and reduces static code size and dynamic instruction
fetch traffic. Another point is that comparisons against zero require non-trivial circuit delay
(especially after the move to static logic in advanced processes) and so are almost as expensive as
arithmetic magnitude compares. Another advantage of a fused compare-and-branch instruction
is that branches are observed earlier in the front-end instruction stream, and so can be predicted
earlier. There is perhaps an advantage to a design with condition codes in the case where multiple
branches can be taken based on the same condition codes, but we believe this case to be relatively
rare.
We considered but did not include static branch hints in the instruction encoding. These
can reduce the pressure on dynamic predictors, but require more instruction encoding space and
software profiling for best results, and can result in poor performance if production runs do not
match profiling runs.
We considered but did not include conditional moves or predicated instructions, which can
e↵ectively replace unpredictable short forward branches. Conditional moves are the simpler of
the two, but are difficult to use with conditional code that might cause exceptions (memory
accesses and floating-point operations). Predication adds additional flag state to a system, addi-
tional instructions to set and clear flags, and additional encoding overhead on every instruction.
Both conditional move and predicated instructions add complexity to out-of-order microarchitec-
tures, adding an implicit third source operand due to the need to copy the original value of the
destination architectural register into the renamed destination physical register if the predicate
is false. Also, static compile-time decisions to use predication instead of branches can result
in lower performance on inputs not included in the compiler training set, especially given that
unpredictable branches are rare, and becoming rarer as branch prediction techniques improve.
We note that various microarchitectural techniques exist to dynamically convert unpredictable
short forward branches into internally predicated code to avoid the cost of flushing pipelines
on a branch mispredict [7, 11, 10] and have been implemented in commercial processors [18].
The simplest techniques just reduce the penalty of recovering from a mispredicted short forward
branch by only flushing instructions in the branch shadow instead of the entire fetch pipeline,
or by fetching instructions from both sides using wide instruction fetch or idle instruction fetch
slots. More complex techniques for out-of-order cores add internal predicates on instructions in
the branch shadow, with the internal predicate value written by the branch instruction, allowing
the branch and following instructions to be executed speculatively and out-of-order with respect
to other code [18].
If the branch condition evaluates to false, the instruction-address-misaligned exception will not be
raised.
RV32I is a load-store architecture, where only load and store instructions access memory and
arithmetic instructions only operate on CPU registers. RV32I provides a 32-bit address space that
is byte-addressed. The EEI will define what portions of the address space are legal to access with
which instructions (e.g., some addresses might be read only, or support word access only). Loads
with a destination of x0 must still raise any exceptions and cause any other side e↵ects even though
the load value is discarded.
The EEI will define whether the memory system is little-endian or big-endian. In RISC-V, endian-
ness is byte-address invariant.
In a system for which endianness is byte-address invariant, the following property holds: if a
byte is stored to memory at some address in some endianness, then a byte-sized load from that
address in any endianness returns the stored value.
In a little-endian configuration, multibyte stores write the least-significant register byte at
the lowest memory byte address, followed by the other register bytes in ascending order of their
significance. Loads similarly transfer the contents of the lesser memory byte addresses to the
less-significant register bytes.
In a big-endian configuration, multibyte stores write the most-significant register byte at the
lowest memory byte address, followed by the other register bytes in descending order of their
significance. Loads similarly transfer the contents of the greater memory byte addresses to the
less-significant register bytes.
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
12 5 3 5 7
o↵set[11:0] base width dest LOAD
31 25 24 20 19 15 14 12 11 7 6 0
imm[11:5] rs2 rs1 funct3 imm[4:0] opcode
7 5 5 3 5 7
o↵set[11:5] src base width o↵set[4:0] STORE
Load and store instructions transfer a value between the registers and memory. Loads are encoded
in the I-type format and stores are S-type. The e↵ective address is obtained by adding register rs1
to the sign-extended 12-bit o↵set. Loads copy a value from memory to register rd. Stores copy the
value in register rs2 to memory.
The LW instruction loads a 32-bit value from memory into rd. LH loads a 16-bit value from memory,
then sign-extends to 32-bits before storing in rd. LHU loads a 16-bit value from memory but then
Volume I: RISC-V Unprivileged ISA V20191214-draft 25
zero extends to 32-bits before storing in rd. LB and LBU are defined analogously for 8-bit values.
The SW, SH, and SB instructions store 32-bit, 16-bit, and 8-bit values from the low bits of register
rs2 to memory.
Regardless of EEI, loads and stores whose e↵ective addresses are naturally aligned shall not raise
an address-misaligned exception. Loads and stores whose e↵ective address is not naturally aligned
to the referenced datatype (i.e., the e↵ective address is not divisible by the size of the access in
bytes) have behavior dependent on the EEI.
An EEI may guarantee that misaligned loads and stores are fully supported, and so the software run-
ning inside the execution environment will never experience a contained or fatal address-misaligned
trap. In this case, the misaligned loads and stores can be handled in hardware, or via an invisible
trap into the execution environment implementation, or possibly a combination of hardware and
invisible trap depending on address.
An EEI may not guarantee misaligned loads and stores are handled invisibly. In this case, loads
and stores that are not naturally aligned may either complete execution successfully or raise an
exception. The exception raised can be either an address-misaligned exception or an access-fault
exception. For a memory access that would otherwise be able to complete except for the mis-
alignment, an access-fault exception can be raised instead of an address-misaligned exception if
the misaligned access should not be emulated, e.g., if accesses to the memory region have side
e↵ects. When an EEI does not guarantee misaligned loads and stores are handled invisibly, the
EEI must define if exceptions caused by address misalignment result in a contained trap (allowing
software running inside the execution environment to handle the trap) or a fatal trap (terminating
execution).
Misaligned accesses are occasionally required when porting legacy code, and help performance on
applications when using any form of packed-SIMD extension or handling externally packed data
structures. Our rationale for allowing EEIs to choose to support misaligned accesses via the
regular load and store instructions is to simplify the addition of misaligned hardware support.
One option would have been to disallow misaligned accesses in the base ISA and then provide
some separate ISA support for misaligned accesses, either special instructions to help software
handle misaligned accesses or a new hardware addressing mode for misaligned accesses. Special
instructions are difficult to use, complicate the ISA, and often add new processor state (e.g.,
SPARC VIS align address o↵set register) or complicate access to existing processor state (e.g.,
MIPS LWL/LWR partial register writes). In addition, for loop-oriented packed-SIMD code,
the extra overhead when operands are misaligned motivates software to provide multiple forms
of loop depending on operand alignment, which complicates code generation and adds to loop
startup overhead. New misaligned hardware addressing modes take considerable space in the
instruction encoding or require very simplified addressing modes (e.g., register indirect only).
Even when misaligned loads and stores complete successfully, these accesses might run extremely
slowly depending on the implementation (e.g., when implemented via an invisible trap). Further-
more, whereas naturally aligned loads and stores are guaranteed to execute atomically, misaligned
loads and stores might not, and hence require additional synchronization to ensure atomicity.
regular load and store instructions. Hardware can then automatically optimize accesses depend-
ing on whether runtime addresses are aligned.
Volume I: RISC-V Unprivileged ISA V20191214-draft 27
31 28 27 26 25 24 23 22 21 20 19 15 14 12 11 7 6 0
fm PI PO PR PW SI SO SR SW rs1 funct3 rd opcode
4 1 1 1 1 1 1 1 1 5 3 5 7
FM predecessor successor 0 FENCE 0 MISC-MEM
The FENCE instruction is used to order device I/O and memory accesses as viewed by other RISC-
V harts and external devices or coprocessors. Any combination of device input (I), device output
(O), memory reads (R), and memory writes (W) may be ordered with respect to any combination
of the same. Informally, no other RISC-V hart or external device can observe any operation in the
successor set following a FENCE before any operation in the predecessor set preceding the FENCE.
Chapter 14 provides a precise description of the RISC-V memory consistency model.
The EEI will define what I/O operations are possible, and in particular, which memory addresses
when accessed by load and store instructions will be treated and ordered as device input and
device output operations respectively rather than memory reads and writes. For example, memory-
mapped I/O devices will typically be accessed with uncached loads and stores that are ordered using
the I and O bits rather than the R and W bits. Instruction-set extensions might also describe new
I/O instructions that will also be ordered using the I and O bits in a FENCE.
The fence mode field fm defines the semantics of the FENCE. A FENCE with fm=0000 orders all
memory operations in its predecessor set before all memory operations in its successor set.
The optional FENCE.TSO instruction is encoded as a FENCE instruction with fm=1000, predeces-
sor=RW, and successor=RW. FENCE.TSO orders all load operations in its predecessor set before
all memory operations in its successor set, and all store operations in its predecessor set before all
store operations in its successor set. This leaves non-AMO store operations in the FENCE.TSO’s
predecessor set unordered with non-AMO loads in its successor set.
The FENCE.TSO encoding was added as an optional extension to the original base FENCE
instruction encoding. The base definition requires that implementations ignore any set bits and
treat the FENCE as global, and so this is a backwards-compatible extension.
The unused fields in the FENCE instructions—rs1 and rd—are reserved for finer-grain fences in
future extensions. For forward compatibility, base implementations shall ignore these fields, and
standard software shall zero these fields. Likewise, many fm and predecessor/successor set settings
in Table 2.2 are also reserved for future use. Base implementations shall treat all such reserved
28 Volume I: RISC-V Unprivileged ISA V20191214-draft
configurations as normal fences with fm=0000, and standard software shall use only non-reserved
configurations.
We chose a relaxed memory model to allow high performance from simple machine implementa-
tions and from likely future coprocessor or accelerator extensions. We separate out I/O ordering
from memory R/W ordering to avoid unnecessary serialization within a device-driver hart and
also to support alternative non-memory paths to control added coprocessors or I/O devices.
Simple implementations may additionally ignore the predecessor and successor fields and always
execute a conservative fence on all operations.
SYSTEM instructions are used to access system functionality that might require privileged ac-
cess and are encoded using the I-type instruction format. These can be divided into two main
classes: those that atomically read-modify-write control and status registers (CSRs), and all other
potentially privileged instructions. CSR instructions are described in Chapter 9, and the base
unprivileged instructions are described in the following section.
The SYSTEM instructions are defined to allow simpler implementations to always trap to a
single software trap handler. More sophisticated implementations might execute more of each
system instruction in hardware.
31 20 19 15 14 12 11 7 6 0
funct12 rs1 funct3 rd opcode
12 5 3 5 7
ECALL 0 PRIV 0 SYSTEM
EBREAK 0 PRIV 0 SYSTEM
These two instructions cause a precise requested trap to the supporting execution environment.
The ECALL instruction is used to make a service request to the execution environment. The EEI
will define how parameters for the service request are passed, but usually these will be in defined
locations in the integer register file.
ECALL and EBREAK were previously named SCALL and SBREAK. The instructions have
the same functionality and encoding, but were renamed to reflect that they can be used more
generally than to call a supervisor-level operating system or debugger.
EBREAK was primarily designed to be used by a debugger to cause execution to stop and fall
back into the debugger. EBREAK is also used by the standard gcc compiler to mark code paths
that should not be executed.
Another use of EBREAK is to support “semihosting”, where the execution environment in-
cludes a debugger that can provide services over an alternate system call interface built around
the EBREAK instruction. Because the RISC-V base ISA does not provide more than one
Volume I: RISC-V Unprivileged ISA V20191214-draft 29
RV32I reserves a large encoding space for HINT instructions, which are usually used to commu-
nicate performance hints to the microarchitecture. HINTs are encoded as integer computational
instructions with rd=x0. Hence, like the NOP instruction, HINTs do not change any architecturally
visible state, except for advancing the pc and any applicable performance counters. Implementa-
tions are always allowed to ignore the encoded hints.
This HINT encoding has been chosen so that simple implementations can ignore HINTs alto-
gether, and instead execute a HINT as a regular computational instruction that happens not to
mutate the architectural state. For example, ADD is a HINT if the destination register is x0; the
five-bit rs1 and rs2 fields encode arguments to the HINT. However, a simple implementation can
simply execute the HINT as an ADD of rs1 and rs2 that writes x0, which has no architecturally
visible e↵ect.
Table 2.3 lists all RV32I HINT code points. 91% of the HINT space is reserved for standard HINTs,
but none are presently defined. The remainder of the HINT space is designated for custom HINTs;
no standard HINTs will ever be defined in this subspace.
No standard hints are presently defined. We anticipate standard hints to eventually include
memory-system spatial and temporal locality hints, branch prediction hints, thread-scheduling
hints, security tags, and instrumentation flags for simulation/emulation.
30 Volume I: RISC-V Unprivileged ISA V20191214-draft