The RISC-V Instruction Set Manual
Volume I: Unprivileged ISA
Document Version 20191213

Editors: Andrew Waterman1 , Krste Asanović1,2
1
SiFive Inc.,
2
CS Division, EECS Department, University of California, Berkeley
andrew@sifive.com, krste@berkeley.edu
December 13, 2019

Contributors to all versions of the spec in alphabetical order (please contact editors to suggest
corrections): Arvind, Krste Asanović, Rimas Avižienis, Jacob Bachmeyer, Christopher F. Batten, Allen J. Baum, Alex Bradbury, Scott Beamer, Preston Briggs, Christopher Celio, Chuanhua
Chang, David Chisnall, Paul Clayton, Palmer Dabbelt, Ken Dockser, Roger Espasa, Shaked Flur,
Stefan Freudenberger, Marc Gauthier, Andy Glew, Jan Gray, Michael Hamburg, John Hauser,
David Horner, Bruce Hoult, Bill Huffman, Alexandre Joannou, Olof Johansson, Ben Keller, David
Kruckemyer, Yunsup Lee, Paul Loewenstein, Daniel Lustig, Yatin Manerkar, Luc Maranget, Margaret Martonosi, Joseph Myers, Vijayanand Nagarajan, Rishiyur Nikhil, Jonas Oberhauser, Stefan
O’Rear, Albert Ou, John Ousterhout, David Patterson, Christopher Pulte, Jose Renau, Josh Scheid,
Colin Schmidt, Peter Sewell, Susmit Sarkar, Michael Taylor, Wesley Terpstra, Matt Thomas,
Tommy Thorn, Caroline Trippel, Ray VanDeWalker, Muralidaran Vijayaraghavan, Megan Wachs,
Andrew Waterman, Robert Watson, Derek Williams, Andrew Wright, Reinoud Zandijk, and Sizhuo
Zhang.
This document is released under a Creative Commons Attribution 4.0 International License.
This document is a derivative of “The RISC-V Instruction Set Manual, Volume I: User-Level ISA
c 2010–2017 Andrew Waterman, Yunsup Lee,
Version 2.1” released under the following license: ⃝David Patterson, Krste Asanović. Creative Commons Attribution 4.0 International License.
Please cite as: “The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document Version
20191213”, Editors Andrew Waterman and Krste Asanović, RISC-V Foundation, December 2019.

Preface
This document describes the RISC-V unprivileged architecture.
The ISA modules marked Ratified have been ratified at this time. The modules marked Frozen
are not expected to change significantly before being put up for ratification. The modules marked
Draft are expected to change before ratification.
The document contains the following versions of the RISC-V ISA modules:
Base
RVWMO
RV32I
RV64I
RV32E
RV128I
Extension
M
A
F
D
Q
C
Counters
L
B
J
T
P
V
Zicsr
Zifencei
Zam
Ztso

Version
2.0
2.1
2.1
1.9
1.7
Version
2.0
2.1
2.2
2.2
2.2
2.0
2.0
0.0
0.0
0.0
0.0
0.2
0.7
2.0
2.0
0.1
0.1

StatusRatified
Ratified
Ratified
Draft
Draft
StatusRatified
Ratified
Ratified
Ratified
Ratified
Ratified
Draft
Draft
Draft
Draft
Draft
Draft
Draft
Ratified
Ratified
Draft
FrozenThe changes in this version of the document include:• The A extension, now version 2.1, was ratified by the board in December 2019.
• Defined big-endian ISA variant.
• Moved N extension for user-mode interrupts into Volume II.
iii

Volume I: RISC-V Unprivileged ISA V20191213

Preface to Document Version 20190608-Base-Ratified
This document describes the RISC-V unprivileged architecture.
The RVWMO memory model has been ratified at this time. The ISA modules marked Ratified, havebeen ratified at this time. The modules marked Frozen are not expected to change significantly
before being put up for ratification. The modules marked Draft are expected to change before
ratification.
The document contains the following versions of the RISC-V ISA modules:
Base
RVWMO
RV32I
RV64I
RV32E
RV128I
Extension
Zifencei
Zicsr
M
A
F
D
Q
C
Ztso
Counters
L
B
J
T
P
V
N
Zam

Version
2.0
2.1
2.1
1.9
1.7
Version
2.0
2.0
2.0
2.0
2.2
2.2
2.2
2.0
0.1
2.0
0.0
0.0
0.0
0.0
0.2
0.7
1.1
0.1

StatusRatified
Ratified
Ratified
Draft
Draft
StatusRatified
Ratified
Ratified
FrozenRatified
Ratified
Ratified
Ratified
Frozen
Draft
Draft
Draft
Draft
Draft
Draft
Draft
Draft
Draft

The changes in this version of the document include:• Moved description to Ratified for the ISA modules ratified by the board in early 2019.
• Removed the A extension from ratification.
• Changed document version scheme to avoid confusion with versions of the ISA modules.
• Incremented the version numbers of the base integer ISA to 2.1, reflecting the presence of theratified RVWMO memory model and exclusion of FENCE.I, counters, and CSR instructions
that were in previous base ISA.
• Incremented the version numbers of the F and D extensions to 2.2, reflecting that version 2.1
changed the canonical NaN, and version 2.2 defined the NaN-boxing scheme and changed thedefinition of the FMIN and FMAX instructions.

Volume I: RISC-V Unprivileged ISA V20191213

iii• Changed name of document to refer to “unprivileged” instructions as part of move to separate
ISA specifications from platform profile mandates.
• Added clearer and more precise definitions of execution environments, harts, traps, and memory accesses.
• Defined instruction-set categories: standard, reserved, custom, non-standard, and nonconforming.
• Removed text implying operation under alternate endianness, as alternate-endianness operation has not yet been defined for RISC-V.
• Changed description of misaligned load and store behavior. The specification now allows
visible misaligned address traps in execution environment interfaces, rather than just mandating invisible handling of misaligned loads and stores in user mode. Also, now allows
access exceptions to be reported for misaligned accesses (including atomics) that should not
be emulated.
• Moved FENCE.I out of the mandatory base and into a separate extension, with Zifencei ISA
name. FENCE.I was removed from the Linux user ABI and is problematic in implementations
with large incoherent instruction and data caches. However, it remains the only standard
instruction-fetch coherence mechanism.
• Removed prohibitions on using RV32E with other extensions.
• Removed platform-specific mandates that certain encodings produce illegal instruction exceptions in RV32E and RV64I chapters.
• Counter/timer instructions are now not considered part of the mandatory base ISA, andso CSR instructions were moved into separate chapter and marked as version 2.0, with theunprivileged counters moved into another separate chapter. The counters are not ready for
ratification as there are outstanding issues, including counter inaccuracies.
• A CSR-access ordering model has been added.
• Explicitly defined the 16-bit half-precision floating-point format for floating-point instructionsin the 2-bit fmt field.
• Defined the signed-zero behavior of FMIN.fmt and FMAX.fmt, and changed their behavior on
signaling-NaN inputs to conform to the minimumNumber and maximumNumber operationsin the proposed IEEE 754-201x specification.
• The memory consistency model, RVWMO, has been defined.
• The “Zam” extension, which permits misaligned AMOs and specifies their semantics, hasbeen defined.
• The “Ztso” extension, which enforces a stricter memory consistency model than RVWMO,
has been defined.
• Improvements to the description and commentary.
• Defined the term IALIGN as shorthand to describe the instruction-address alignment constraint.
• Removed text of P extension chapter as now superseded by active task group documents.
• Removed text of V extension chapter as now superseded by separate vector extension draft
document.

iv

Volume I: RISC-V Unprivileged ISA V20191213

Preface to Document Version 2.2
This is version 2.2 of the document describing the RISC-V user-level architecture. The document
contains the following versions of the RISC-V ISA modules:
Base
RV32I
RV32E
RV64I
RV128I
Extension
M
A
F
D
Q
L
C
B
J
T
P
V
N

Version
2.0
1.9
2.0
1.7
Version
2.0
2.0
2.0
2.0
2.0
0.0
2.0
0.0
0.0
0.0
0.1
0.7
1.1

Draft Frozen?
YNYN
Frozen?
Y
Y
Y
Y
Y
N
Y
N
N
N
N
N
N

To date, no parts of the standard have been officially ratified by the RISC-V Foundation, but
the components labeled “frozen” above are not expected to change during the ratification process
beyond resolving ambiguities and holes in the specification.
The major changes in this version of the document include:• The previous version of this document was released under a Creative Commons Attribution
4.0 International License by the original authors, and this and future versions of this document
will be released under the same license.
• Rearranged chapters to put all extensions first in canonical order.
• Improvements to the description and commentary.
• Modified implicit hinting suggestion on JALR to support more efficient macro-op fusion of
LUI/JALR and AUIPC/JALR pairs.
• Clarification of constraints on load-reserved/store-conditional sequences.
• A new table of control and status register (CSR) mappings.
• Clarified purpose and behavior of high-order bits of fcsr.
• Corrected the description of the FNMADD.fmt and FNMSUB.fmt instructions, which hadsuggested the incorrect sign of a zero result.
• Instructions FMV.S.X and FMV.X.S were renamed to FMV.W.X and FMV.X.W respectively
to be more consistent with their semantics, which did not change. The old names will continue
to be supported in the tools.

Volume I: RISC-V Unprivileged ISA V20191213

v• Specified behavior of narrower (<FLEN) floating-point values held in wider f registers using
NaN-boxing model.
• Defined the exception behavior of FMA(∞, 0, qNaN).
• Added note indicating that the P extension might be reworked into an integer packed-SIMD
proposal for fixed-point operations using the integer registers.
• A draft proposal of the V vector instruction-set extension.
• An early draft proposal of the N user-level traps extension.
• An expanded pseudoinstruction listing.
• Removal of the calling convention chapter, which has been superseded by the RISC-V ELF
psABI Specification [1].
• The C extension has been frozen and renumbered version 2.0.

Preface to Document Version 2.1
This is version 2.1 of the document describing the RISC-V user-level architecture. Note the frozen
user-level ISA base and extensions IMAFDQ version 2.0 have not changed from the previous versionof this document [25], but some specification holes have been fixed and the documentation has been
improved. Some changes have been made to the software conventions.
• Numerous additions and improvements to the commentary sections.
• Separate version numbers for each chapter.
• Modification to long instruction encodings >64 bits to avoid moving the rd specifier in very
long instruction formats.
• CSR instructions are now described in the base integer format where the counter registers
are introduced, as opposed to only being introduced later in the floating-point section (andthe companion privileged architecture manual).
• The SCALL and SBREAK instructions have been renamed to ECALL and EBREAK, respectively. Their encoding and functionality are unchanged.
• Clarification of floating-point NaN handling, and a new canonical NaN value.
• Clarification of values returned by floating-point to integer conversions that overflow.
• Clarification of LR/SC allowed successes and required failures, including use of compressed
instructions in the sequence.
• A new RV32E base ISA proposal for reduced integer register counts, supports MAC extensions.
• A revised calling convention.
• Relaxed stack alignment for soft-float calling convention, and description of the RV32E calling
convention.
• A revised proposal for the C compressed extension, version 1.9.

viVolume I: RISC-V Unprivileged ISA V20191213

Preface to Version 2.0
This is the second release of the user ISA specification, and we intend the specification of thebase user ISA plus general extensions (i.e., IMAFD) to remain fixed for future development. The
following changes have been made since Version 1.0 [24] of this ISA specification.
• The ISA has been divided into an integer base with several standard extensions.
• The instruction formats have been rearranged to make immediate encoding more efficient.
• The base ISA has been defined to have a little-endian memory system, with big-endian orbi-endian as non-standard variants.
• Load-Reserved/Store-Conditional (LR/SC) instructions have been added in the atomic instruction extension.
• AMOs and LR/SC can support the release consistency model.
• The FENCE instruction provides finer-grain memory and I/O orderings.
• An AMO for fetch-and-XOR (AMOXOR) has been added, and the encoding for AMOSWAP
has been changed to make room.
• The AUIPC instruction, which adds a 20-bit upper immediate to the PC, replaces the RDNPC
instruction, which only read the current PC value. This results in significant savings for
position-independent code.
• The JAL instruction has now moved to the U-Type format with an explicit destination
register, and the J instruction has been dropped being replaced by JAL with rd=x0. This
removes the only instruction with an implicit destination register and removes the J-Type
instruction format from the base ISA. There is an accompanying reduction in JAL reach, but
a significant reduction in base ISA complexity.
• The static hints on the JALR instruction have been dropped. The hints are redundant withthe rd and rs1 register specifiers for code compliant with the standard calling convention.
• The JALR instruction now clears the lowest bit of the calculated target address, to simplify
hardware and to allow auxiliary information to be stored in function pointers.
• The MFTX.S and MFTX.D instructions have been renamed to FMV.X.S and FMV.X.D,
respectively. Similarly, MXTF.S and MXTF.D instructions have been renamed to FMV.S.X
and FMV.D.X, respectively.
• The MFFSR and MTFSR instructions have been renamed to FRCSR and FSCSR, respectively. FRRM, FSRM, FRFLAGS, and FSFLAGS instructions have been added to individually access the rounding mode and exception flags subfields of the fcsr.
• The FMV.X.S and FMV.X.D instructions now source their operands from rs1, instead of rs2.
This change simplifies datapath design.
• FCLASS.S and FCLASS.D floating-point classify instructions have been added.
• A simpler NaN generation and propagation scheme has been adopted.
• For RV32I, the system performance counters have been extended to 64-bits wide, with separate
read access to the upper and lower 32 bits.
• Canonical NOP and MV encodings have been defined.
• Standard instruction-length encodings have been defined for 48-bit, 64-bit, and >64-bit instructions.
• Description of a 128-bit address space variant, RV128, has been added.
• Major opcodes in the 32-bit base instruction format have been allocated for user-definedcustom extensions.

Volume I: RISC-V Unprivileged ISA V20191213

vii• A typographical error that suggested that stores source their data from rd has been corrected
to refer to rs2.

viii

Volume I: RISC-V Unprivileged ISA V20191213

Contents
Prefacei

1 Introduction

1

1.1

RISC-V Hardware Platform Terminology . . . . . . . . . . . . . . . . . . . . . . . .

2

1.2

RISC-V Software Execution Environments and Harts . . . . . . . . . . . . . . . . . .

3

1.3

RISC-V ISA Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

1.4

Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

1.5

Base Instruction-Length Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7

1.6

Exceptions, Traps, and Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

1.7

UNSPECIFIED Behaviors and Values . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 RV32I Base Integer Instruction Set, Version 2.1

13

2.1

Programmers’ Model for Base Integer ISA . . . . . . . . . . . . . . . . . . . . . . . . 13

2.2

Base Instruction Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.3

Immediate Encoding Variants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

2.4

Integer Computational Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.5

Control Transfer Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.6

Load and Store Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.7

Memory Ordering Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

2.8

Environment Call and Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.9

HINT Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28ix

xVolume I: RISC-V Unprivileged ISA V20191213

3 “Zifencei” Instruction-Fetch Fence, Version 2.031

4 RV32E Base Integer Instruction Set, Version 1.9

33

4.1

RV32E Programmers’ Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

4.2

RV32E Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5 RV64I Base Integer Instruction Set, Version 2.1

35

5.1

Register State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.2

Integer Computational Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.3

Load and Store Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.4

HINT Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

6 RV128I Base Integer Instruction Set, Version 1.7

41

7 “M” Standard Extension for Integer Multiplication and Division, Version 2.0

43

7.1

Multiplication Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

7.2

Division Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

8 “A” Standard Extension for Atomic Instructions, Version 2.1

47

8.1

Specifying Ordering of Atomic Instructions . . . . . . . . . . . . . . . . . . . . . . . 47

8.2

Load-Reserved/Store-Conditional Instructions . . . . . . . . . . . . . . . . . . . . . . 48

8.3

Eventual Success of Store-Conditional Instructions . . . . . . . . . . . . . . . . . . . 51

8.4

Atomic Memory Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

9 “Zicsr”, Control and Status Register (CSR) Instructions, Version 2.0
9.155

CSR Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

10 Counters59

10.1 Base Counters and Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
10.2 Hardware Performance Counters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
11 “F” Standard Extension for Single-Precision Floating-Point, Version 2.2

63Volume I: RISC-V Unprivileged ISA V20191213

xi

11.1 F Register State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
11.2 Floating-Point Control and Status Register . . . . . . . . . . . . . . . . . . . . . . . 65
11.3 NaN Generation and Propagation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
11.4 Subnormal Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11.5 Single-Precision Load and Store Instructions . . . . . . . . . . . . . . . . . . . . . . . 67
11.6 Single-Precision Floating-Point Computational Instructions . . . . . . . . . . . . . . 67
11.7 Single-Precision Floating-Point Conversion and Move Instructions. . . . . . . . . . 69

11.8 Single-Precision Floating-Point Compare Instructions . . . . . . . . . . . . . . . . . . 71
11.9 Single-Precision Floating-Point Classify Instruction . . . . . . . . . . . . . . . . . . . 71
12 “D” Standard Extension for Double-Precision Floating-Point, Version 2.2

73

12.1 D Register State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
12.2 NaN Boxing of Narrower Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
12.3 Double-Precision Load and Store Instructions . . . . . . . . . . . . . . . . . . . . . . 74
12.4 Double-Precision Floating-Point Computational Instructions . . . . . . . . . . . . . . 75
12.5 Double-Precision Floating-Point Conversion and Move Instructions . . . . . . . . . . 75
12.6 Double-Precision Floating-Point Compare Instructions . . . . . . . . . . . . . . . . . 77
12.7 Double-Precision Floating-Point Classify Instruction . . . . . . . . . . . . . . . . . . 77
13 “Q” Standard Extension for Quad-Precision Floating-Point, Version 2.2

79

13.1 Quad-Precision Load and Store Instructions . . . . . . . . . . . . . . . . . . . . . . . 79
13.2 Quad-Precision Computational Instructions . . . . . . . . . . . . . . . . . . . . . . . 80
13.3 Quad-Precision Convert and Move Instructions . . . . . . . . . . . . . . . . . . . . . 80
13.4 Quad-Precision Floating-Point Compare Instructions . . . . . . . . . . . . . . . . . . 81
13.5 Quad-Precision Floating-Point Classify Instruction . . . . . . . . . . . . . . . . . . . 82
14 RVWMO Memory Consistency Model, Version 0.1

8314.1 Definition of the RVWMO Memory Model . . . . . . . . . . . . . . . . . . . . . . . . 84
14.2 CSR Dependency Tracking Granularity . . . . . . . . . . . . . . . . . . . . . . . . . 88

xiiVolume I: RISC-V Unprivileged ISA V20191213
14.3 Source and Destination Register Listings . . . . . . . . . . . . . . . . . . . . . . . . . 88

15 “L” Standard Extension for Decimal Floating-Point, Version 0.0

9515.1 Decimal Floating-Point Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
16 “C” Standard Extension for Compressed Instructions, Version 2.0

97

16.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
16.2 Compressed Instruction Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
16.3 Load and Store Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
16.4 Control Transfer Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
16.5 Integer Computational Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
16.6 Usage of C Instructions in LR/SC Sequences . . . . . . . . . . . . . . . . . . . . . . 110
16.7 HINT Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
16.8 RVC Instruction Set Listings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
17 “B” Standard Extension for Bit Manipulation, Version 0.0

115

18 “J” Standard Extension for Dynamically Translated Languages, Version 0.0

117

19 “T” Standard Extension for Transactional Memory, Version 0.0

119

20 “P” Standard Extension for Packed-SIMD Instructions, Version 0.2

121

21 “V” Standard Extension for Vector Operations, Version 0.7

123

22 “Zam” Standard Extension for Misaligned Atomics, v0.1

125

23 “Ztso” Standard Extension for Total Store Ordering, v0.1

127

24 RV32/64G Instruction Set Listings

129

25 RISC-V Assembly Programmer’s Handbook

137

26 Extending RISC-V

141

Volume I: RISC-V Unprivileged ISA V20191213

xiii

26.1 Extension Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
26.2 RISC-V Extension Design Philosophy . . . . . . . . . . . . . . . . . . . . . . . . . . 144
26.3 Extensions within fixed-width 32-bit instruction format . . . . . . . . . . . . . . . . 144
26.4 Adding aligned 64-bit instruction extensions . . . . . . . . . . . . . . . . . . . . . . . 146
26.5 Supporting VLIW encodings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

27 ISA Extension Naming Conventions

149

27.1 Case Sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
27.2 Base Integer ISA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
27.3 Instruction-Set Extension Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
27.4 Version Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
27.5 Underscores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
27.6 Additional Standard Extension Names . . . . . . . . . . . . . . . . . . . . . . . . . . 150
27.7 Supervisor-level Instruction-Set Extensions . . . . . . . . . . . . . . . . . . . . . . . 151
27.8 Hypervisor-level Instruction-Set Extensions . . . . . . . . . . . . . . . . . . . . . . . 151
27.9 Machine-level Instruction-Set Extensions . . . . . . . . . . . . . . . . . . . . . . . . . 151
27.10Non-Standard Extension Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
27.11Subset Naming Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
28 History and Acknowledgments

153

28.1 “Why Develop a new ISA?” Rationale from Berkeley Group . . . . . . . . . . . . . . 153
28.2 History from Revision 1.0 of ISA manual . . . . . . . . . . . . . . . . . . . . . . . . . 155
28.3 History from Revision 2.0 of ISA manual . . . . . . . . . . . . . . . . . . . . . . . . . 156
28.4 History from Revision 2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
28.5 History from Revision 2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
28.6 History for Revision 2.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
28.7 Funding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
A RVWMO Explanatory Material, Version 0.1

161

xiv

Volume I: RISC-V Unprivileged ISA V20191213
A.1 Why RVWMO? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
A.2 Litmus Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
A.3 Explaining the RVWMO Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
A.3.1 Preserved Program Order and Global Memory Order . . . . . . . . . . . . . . 163
A.3.2 Load Value Axiom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
A.3.3 Atomicity Axiom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
A.3.4 Progress Axiom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
A.3.5 Overlapping-Address Orderings (Rules 1–3) . . . . . . . . . . . . . . . . . . . 168
A.3.6 Fences (Rule 4) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
A.3.7 Explicit Synchronization (Rules 5–8) . . . . . . . . . . . . . . . . . . . . . . . 171
A.3.8 Syntactic Dependencies (Rules 9–11) . . . . . . . . . . . . . . . . . . . . . . . 173
A.3.9 Pipeline Dependencies (Rules 12–13) . . . . . . . . . . . . . . . . . . . . . . . 176
A.4 Beyond Main Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
A.4.1 Coherence and Cacheability . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
A.4.2 I/O Ordering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
A.5 Code Porting and Mapping Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . 180
A.6 Implementation Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
A.6.1 Possible Future Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
A.7 Known Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
A.7.1 Mixed-size RSW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188

B Formal Memory Model Specifications, Version 0.1

191

B.1 Formal Axiomatic Specification in Alloy . . . . . . . . . . . . . . . . . . . . . . . . . 192
B.2 Formal Axiomatic Specification in Herd . . . . . . . . . . . . . . . . . . . . . . . . . 197
B.3 An Operational Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
B.3.1 Intra-instruction Pseudocode Execution . . . . . . . . . . . . . . . . . . . . . 204
B.3.2 Instruction Instance State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
B.3.3 Hart State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

Volume I: RISC-V Unprivileged ISA V20191213

xv

B.3.4 Shared Memory State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
B.3.5 Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
B.3.6 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

xvi

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 1

Introduction
RISC-V (pronounced “risk-five”) is a new instruction-set architecture (ISA) that was originallydesigned to support computer architecture research and education, but which we now hope will
also become a standard free and open architecture for industry implementations. Our goals in
defining RISC-V include:• A completely open ISA that is freely available to academia and industry.
• A real ISA suitable for direct native hardware implementation, not just simulation or binarytranslation.
• An ISA that avoids “over-architecting” for a particular microarchitecture style (e.g., microcoded, in-order, decoupled, out-of-order) or implementation technology (e.g., full-custom,
ASIC, FPGA), but which allows efficient implementation in any of these.
• An ISA separated into a small base integer ISA, usable by itself as a base for customized
accelerators or for educational purposes, and optional standard extensions, to support generalpurpose software development.
• Support for the revised 2008 IEEE-754 floating-point standard [7].
• An ISA supporting extensive ISA extensions and specialized variants.
• Both 32-bit and 64-bit address space variants for applications, operating system kernels, andhardware implementations.
• An ISA with support for highly-parallel multicore or manycore implementations, including
heterogeneous multiprocessors.
• Optional variable-length instructions to both expand available instruction encoding space andto support an optional dense instruction encoding for improved performance, static code size,and energy efficiency.
• A fully virtualizable ISA to ease hypervisor development.
• An ISA that simplifies experiments with new privileged architecture designs.
Commentary on our design decisions is formatted as in this paragraph. This non-normative text
can be skipped if the reader is only interested in the specification itself.
The name RISC-V was chosen to represent the fifth major RISC ISA design from UC Berkeley(RISC-I [15], RISC-II [8], SOAR [21], and SPUR [11] were the first four). We also pun on theuse of the Roman numeral “V” to signify “variations” and “vectors”, as support for a range of1

2

Volume I: RISC-V Unprivileged ISA V20191213
architecture research, including various data-parallel accelerators, is an explicit goal of the ISA
design.

The RISC-V ISA is defined avoiding implementation details as much as possible (although commentary is included on implementation-driven decisions) and should be read as the software-visible
interface to a wide variety of implementations rather than as the design of a particular hardware
artifact. The RISC-V manual is structured in two volumes. This volume covers the design ofthe base unprivileged instructions, including optional unprivileged ISA extensions. Unprivileged
instructions are those that are generally usable in all privilege modes in all privileged architectures,
though behavior might vary depending on privilege mode and privilege architecture. The second
volume provides the design of the first (“classic”) privileged architecture. The manuals use IEC
80000-13:2008 conventions, with a byte of 8 bits.
In the unprivileged ISA design, we tried to remove any dependence on particular microarchitectural features, such as cache line size, or on privileged architecture details, such as pagetranslation. This is both for simplicity and to allow maximum flexibility for alternative microarchitectures or alternative privileged architectures.

1.1

RISC-V Hardware Platform Terminology

A RISC-V hardware platform can contain one or more RISC-V-compatible processing cores together with other non-RISC-V-compatible cores, fixed-function accelerators, various physical memory structures, I/O devices, and an interconnect structure to allow the components to communicate.
A component is termed a core if it contains an independent instruction fetch unit. A RISC-Vcompatible core might support multiple RISC-V-compatible hardware threads, or harts, throughmultithreading.
A RISC-V core might have additional specialized instruction-set extensions or an added coprocessor.
We use the term coprocessor to refer to a unit that is attached to a RISC-V core and is mostly
sequenced by a RISC-V instruction stream, but which contains additional architectural state andinstruction-set extensions, and possibly some limited autonomy relative to the primary RISC-V
instruction stream.
We use the term accelerator to refer to either a non-programmable fixed-function unit or a core thatcan operate autonomously but is specialized for certain tasks. In RISC-V systems, we expect many
programmable accelerators will be RISC-V-based cores with specialized instruction-set extensions
and/or customized coprocessors. An important class of RISC-V accelerators are I/O accelerators,
which offload I/O processing tasks from the main application cores.
The system-level organization of a RISC-V hardware platform can range from a single-core microcontroller to a many-thousand-node cluster of shared-memory manycore server nodes. Even small
systems-on-a-chip might be structured as a hierarchy of multicomputers and/or multiprocessors tomodularize development effort or to provide secure isolation between subsystems.

Volume I: RISC-V Unprivileged ISA V20191213

1.2

3

RISC-V Software Execution Environments and Harts

The behavior of a RISC-V program depends on the execution environment in which it runs. A
RISC-V execution environment interface (EEI) defines the initial state of the program, the number
and type of harts in the environment including the privilege modes supported by the harts, theaccessibility and attributes of memory and I/O regions, the behavior of all legal instructions executed on each hart (i.e., the ISA is one component of the EEI), and the handling of any interrupts
or exceptions raised during execution including environment calls. Examples of EEIs include theLinux application binary interface (ABI), or the RISC-V supervisor binary interface (SBI). The
implementation of a RISC-V execution environment can be pure hardware, pure software, or a
combination of hardware and software. For example, opcode traps and software emulation can beused to implement functionality not provided in hardware. Examples of execution environment
implementations include:• “Bare metal” hardware platforms where harts are directly implemented by physical processor
threads and instructions have full access to the physical address space. The hardware platform
defines an execution environment that begins at power-on reset.
• RISC-V operating systems that provide multiple user-level execution environments by multiplexing user-level harts onto available physical processor threads and by controlling accessto memory via virtual memory.
• RISC-V hypervisors that provide multiple supervisor-level execution environments for guest
operating systems.
• RISC-V emulators, such as Spike, QEMU or rv8, which emulate RISC-V harts on an underlying x86 system, and which can provide either a user-level or a supervisor-level execution
environment.

A bare hardware platform can be considered to define an EEI, where the accessible harts, memory,and other devices populate the environment, and the initial state is that at power-on reset.
Generally, most software is designed to use a more abstract interface to the hardware, as more
abstract EEIs provide greater portability across different hardware platforms. Often EEIs arelayered on top of one another, where one higher-level EEI uses another lower-level EEI.

From the perspective of software running in a given execution environment, a hart is a resource that
autonomously fetches and executes RISC-V instructions within that execution environment. In thisrespect, a hart behaves like a hardware thread resource even if time-multiplexed onto real hardware
by the execution environment. Some EEIs support the creation and destruction of additional harts,for example, via environment calls to fork new harts.
The execution environment is responsible for ensuring the eventual forward progress of each of its
harts. For a given hart, that responsibility is suspended while the hart is exercising a mechanismthat explicitly waits for an event, such as the wait-for-interrupt instruction defined in Volume IIof this specification; and that responsibility ends if the hart is terminated. The following events
constitute forward progress:• The retirement of an instruction.
• A trap, as defined in Section 1.6.

4

Volume I: RISC-V Unprivileged ISA V20191213• Any other event defined by an extension to constitute forward progress.

The term hart was introduced in the work on Lithe [13, 14] to provide a term to represent an
abstract execution resource as opposed to a software thread programming abstraction.
The important distinction between a hardware thread (hart) and a software thread context
is that the software running inside an execution environment is not responsible for causing
progress of each of its harts; that is the responsibility of the outer execution environment. So
the environment’s harts operate like hardware threads from the perspective of the software inside
the execution environment.
An execution environment implementation might time-multiplex a set of guest harts onto
fewer host harts provided by its own execution environment but must do so in a way that guest
harts operate like independent hardware threads. In particular, if there are more guest harts thanhost harts then the execution environment must be able to preempt the guest harts and must not
wait indefinitely for guest software on a guest hart to ”yield” control of the guest hart.

1.3

RISC-V ISA Overview

A RISC-V ISA is defined as a base integer ISA, which must be present in any implementation, plus
optional extensions to the base ISA. The base integer ISAs are very similar to that of the early
RISC processors except with no branch delay slots and with support for optional variable-length
instruction encodings. A base is carefully restricted to a minimal set of instructions sufficient toprovide a reasonable target for compilers, assemblers, linkers, and operating systems (with additional privileged operations), and so provides a convenient ISA and software toolchain “skeleton”
around which more customized processor ISAs can be built.
Although it is convenient to speak of the RISC-V ISA, RISC-V is actually a family of related ISAs,
of which there are currently four base ISAs. Each base integer instruction set is characterized by
the width of the integer registers and the corresponding size of the address space and by the numberof integer registers. There are two primary base integer variants, RV32I and RV64I, described in
Chapters 2 and 5, which provide 32-bit or 64-bit address spaces respectively. We use the term
XLEN to refer to the width of an integer register in bits (either 32 or 64). Chapter 4 describes
the RV32E subset variant of the RV32I base instruction set, which has been added to support
small microcontrollers, and which has half the number of integer registers. Chapter 6 sketches afuture RV128I variant of the base integer instruction set supporting a flat 128-bit address space(XLEN=128). The base integer instruction sets use a two’s-complement representation for signed
integer values.
Although 64-bit address spaces are a requirement for larger systems, we believe 32-bit address
spaces will remain adequate for many embedded and client devices for decades to come and will
be desirable to lower memory traffic and energy consumption. In addition, 32-bit address spaces
are sufficient for educational purposes. A larger flat 128-bit address space might eventually berequired, so we ensured this could be accommodated within the RISC-V ISA framework.
The four base ISAs in RISC-V are treated as distinct base ISAs. A common question is whyis there not a single ISA, and in particular, why is RV32I not a strict subset of RV64I? Someearlier ISA designs (SPARC, MIPS) adopted a strict superset policy when increasing address
space size to support running existing 32-bit binaries on new 64-bit hardware.

Volume I: RISC-V Unprivileged ISA V20191213

5

The main advantage of explicitly separating base ISAs is that each base ISA can be optimized for its needs without requiring to support all the operations needed for other base ISAs.
For example, RV64I can omit instructions and CSRs that are only needed to cope with the narrower registers in RV32I. The RV32I variants can use encoding space otherwise reserved for
instructions only required by wider address-space variants.
The main disadvantage of not treating the design as a single ISA is that it complicatesthe hardware needed to emulate one base ISA on another (e.g., RV32I on RV64I). However,differences in addressing and illegal instruction traps generally mean some mode switch would
be required in hardware in any case even with full superset instruction encodings, and the different
RISC-V base ISAs are similar enough that supporting multiple versions is relatively low cost.
Although some have proposed that the strict superset design would allow legacy 32-bit libraries
to be linked with 64-bit code, this is impractical in practice, even with compatible encodings, due
to the differences in software calling conventions and system-call interfaces.
The RISC-V privileged architecture provides fields in misa to control the unprivileged ISA ateach level to support emulating different base ISAs on the same hardware. We note that newer
SPARC and MIPS ISA revisions have deprecated support for running 32-bit code unchanged on
64-bit systems.
A related question is why there is a different encoding for 32-bit adds in RV32I (ADD) and
RV64I (ADDW)? The ADDW opcode could be used for 32-bit adds in RV32I and ADDD for
64-bit adds in RV64I, instead of the existing design which uses the same opcode ADD for 32bit adds in RV32I and 64-bit adds in RV64I with a different opcode ADDW for 32-bit adds in
RV64I. This would also be more consistent with the use of the same LW opcode for 32-bit loadin both RV32I and RV64I. The very first versions of RISC-V ISA did have a variant of thisalternate design, but the RISC-V design was changed to the current choice in January 2011.
Our focus was on supporting 32-bit integers in the 64-bit ISA not on providing compatibility
with the 32-bit ISA, and the motivation was to remove the asymmetry that arose from having
not all opcodes in RV32I have a *W suffix (e.g., ADDW, but AND not ANDW). In hindsight,
this was perhaps not well-justified and a consequence of designing both ISAs at the same time
as opposed to adding one later to sit on top of another, and also from a belief we had to foldplatform requirements into the ISA spec which would imply that all the RV32I instructions would
have been required in RV64I. It is too late to change the encoding now, but this is also of little
practical consequence for the reasons stated above.
It has been noted we could enable the *W variants as an extension to RV32I systems toprovide a common encoding across RV64I and a future RV32 variant.

RISC-V has been designed to support extensive customization and specialization. Each base integer
ISA can be extended with one or more optional instruction-set extensions, and we divide each RISCV instruction-set encoding space (and related encoding spaces such as the CSRs) into three disjoint
categories: standard, reserved, and custom. Standard encodings are defined by the Foundation,and shall not conflict with other standard extensions for the same base ISA. Reserved encodings
are currently not defined but are saved for future standard extensions. We use the term nonstandard to describe an extension that is not defined by the Foundation. Custom encodings shallnever be used for standard extensions and are made available for vendor-specific non-standard
extensions. We use the term non-conforming to describe a non-standard extension that uses eithera standard or a reserved encoding (i.e., custom extensions are not non-conforming). Instruction-set
extensions are generally shared but may provide slightly different functionality depending on thebase ISA. Chapter 26 describes various ways of extending the RISC-V ISA. We have also developed
a naming convention for RISC-V base instructions and instruction-set extensions, described indetail in Chapter 27.
To support more general software development, a set of standard extensions are defined to provide
integer multiply/divide, atomic operations, and single and double-precision floating-point arith-6

Volume I: RISC-V Unprivileged ISA V20191213

metic. The base integer ISA is named “I” (prefixed by RV32 or RV64 depending on integer register
width), and contains integer computational instructions, integer loads, integer stores, and controlflow instructions. The standard integer multiplication and division extension is named “M”, andadds instructions to multiply and divide values held in the integer registers. The standard atomic
instruction extension, denoted by “A”, adds instructions that atomically read, modify, and write
memory for inter-processor synchronization. The standard single-precision floating-point extension, denoted by “F”, adds floating-point registers, single-precision computational instructions, andsingle-precision loads and stores. The standard double-precision floating-point extension, denotedby “D”, expands the floating-point registers, and adds double-precision computational instructions, loads, and stores. The standard “C” compressed instruction extension provides narrower
16-bit forms of common instructions.
Beyond the base integer ISA and the standard GC extensions, we believe it is rare that a new
instruction will provide a significant benefit for all applications, although it may be very beneficial
for a certain domain. As energy efficiency concerns are forcing greater specialization, we believe it
is important to simplify the required portion of an ISA specification. Whereas other architectures
usually treat their ISA as a single entity, which changes to a new version as instructions are added
over time, RISC-V will endeavor to keep the base and each standard extension constant over time,and instead layer new instructions as further optional extensions. For example, the base integer
ISAs will continue as fully supported standalone ISAs, regardless of any subsequent extensions.

1.4

MemoryA RISC-V hart has a single byte-addressable address space of 2XLEN bytes for all memory accesses.
A word of memory is defined as 32 bits (4 bytes). Correspondingly, a halfword is 16 bits (2 bytes), a
doubleword is 64 bits (8 bytes), and a quadword is 128 bits (16 bytes). The memory address space iscircular, so that the byte at address 2XLEN − 1 is adjacent to the byte at address zero. Accordingly,
memory address computations done by the hardware ignore overflow and instead wrap aroundmodulo 2XLEN .
The execution environment determines the mapping of hardware resources into a hart’s address
space. Different address ranges of a hart’s address space may (1) be vacant, or (2) contain main
memory, or (3) contain one or more I/O devices. Reads and writes of I/O devices may havevisible side effects, but accesses to main memory cannot. Although it is possible for the execution
environment to call everything in a hart’s address space an I/O device, it is usually expected thatsome portion will be specified as main memory.
When a RISC-V platform has multiple harts, the address spaces of any two harts may be entirely
the same, or entirely different, or may be partly different but sharing some subset of resources,
mapped into the same or different address ranges.
For a purely “bare metal” environment, all harts may see an identical address space, accessed
entirely by physical addresses. However, when the execution environment includes an operating
system employing address translation, it is common for each hart to be given a virtual address
space that is largely or entirely its own.

Volume I: RISC-V Unprivileged ISA V20191213

7

Executing each RISC-V machine instruction entails one or more memory accesses, subdivided into
implicit and explicit accesses. For each instruction executed, an implicit memory read (instruction
fetch) is done to obtain the encoded instruction to execute. Many RISC-V instructions performno further memory accesses beyond instruction fetch. Specific load and store instructions perform
an explicit read or write of memory at an address determined by the instruction. The execution
environment may dictate that instruction execution performs other implicit memory accesses (suchas to implement address translation) beyond those documented for the unprivileged ISA.
The execution environment determines what portions of the non-vacant address space are accessible
for each kind of memory access. For example, the set of locations that can be implicitly read for
instruction fetch may or may not have any overlap with the set of locations that can be explicitly
read by a load instruction; and the set of locations that can be explicitly written by a store
instruction may be only a subset of locations that can be read. Ordinarily, if an instruction
attempts to access memory at an inaccessible address, an exception is raised for the instruction.
Vacant locations in the address space are never accessible.
Except when specified otherwise, implicit reads that do not raise an exception and that have noside effects may occur arbitrarily early and speculatively, even before the machine could possibly
prove that the read will be needed. For instance, a valid implementation could attempt to read allof main memory at the earliest opportunity, cache as many fetchable (executable) bytes as possible
for later instruction fetches, and avoid reading main memory for instruction fetches ever again.
To ensure that certain implicit reads are ordered only after writes to the same memory locations,software must execute specific fence or cache-control instructions defined for this purpose (such as
the FENCE.I instruction defined in Chapter 3).
The memory accesses (implicit or explicit) made by a hart may appear to occur in a different orderas perceived by another hart or by any other agent that can access the same memory. This perceived
reordering of memory accesses is always constrained, however, by the applicable memory consistencymodel. The default memory consistency model for RISC-V is the RISC-V Weak Memory Ordering(RVWMO), defined in Chapter 14 and in appendices. Optionally, an implementation may adopt
the stronger model of Total Store Ordering, as defined in Chapter 23. The execution environment
may also add constraints that further limit the perceived reordering of memory accesses. Since the
RVWMO model is the weakest model allowed for any RISC-V implementation, software written forthis model is compatible with the actual memory consistency rules of all RISC-V implementations.
As with implicit reads, software must execute fence or cache-control instructions to ensure specificordering of memory accesses beyond the requirements of the assumed memory consistency modeland execution environment.

1.5

Base Instruction-Length Encoding

The base RISC-V ISA has fixed-length 32-bit instructions that must be naturally aligned on 32-bit
boundaries. However, the standard RISC-V encoding scheme is designed to support ISA extensions
with variable-length instructions, where each instruction can be any number of 16-bit instruction
parcels in length and parcels are naturally aligned on 16-bit boundaries. The standard compressed
ISA extension described in Chapter 16 reduces code size by providing compressed 16-bit instructions
and relaxes the alignment constraints to allow all instructions (16 bit and 32 bit) to be aligned onany 16-bit boundary to improve code density.

8

Volume I: RISC-V Unprivileged ISA V20191213

We use the term IALIGN (measured in bits) to refer to the instruction-address alignment constraint
the implementation enforces. IALIGN is 32 bits in the base ISA, but some ISA extensions, including
the compressed ISA extension, relax IALIGN to 16 bits. IALIGN may not take on any value otherthan 16 or 32.
We use the term ILEN (measured in bits) to refer to the maximum instruction length supported
by an implementation, and which is always a multiple of IALIGN. For implementations supporting
only a base instruction set, ILEN is 32 bits. Implementations supporting longer instructions havelarger values of ILEN.
Figure 1.1 illustrates the standard RISC-V instruction-length encoding convention. All the 32-bit
instructions in the base ISA have their lowest two bits set to 11. The optional compressed 16-bit
instruction-set extensions have their lowest two bits equal to 00, 01, or 10.

Expanded Instruction-Length Encoding
A portion of the 32-bit instruction-encoding space has been tentatively allocated for instructions
longer than 32 bits. The entirety of this space is reserved at this time, and the following proposal
for encoding instructions longer than 32 bits is not considered frozen.
Standard instruction-set extensions encoded with more than 32 bits have additional low-order bits
set to 1, with the conventions for 48-bit and 64-bit lengths shown in Figure 1.1. Instruction lengths
between 80 bits and 176 bits are encoded using a 3-bit field in bits [14:12] giving the number of
16-bit words in addition to the first 5×16-bit words. The encoding with bits [14:12] set to 111 isreserved for future longer instruction encodings.

Byte Address:

xxxxxxxxxxxxxxaa

16-bit (aa ̸= 11)xxxxxxxxxxxxxxxx

xxxxxxxxxxxbbb11

32-bit (bbb ̸= 111)

· · ·xxxx

xxxxxxxxxxxxxxxx

xxxxxxxxxx011111

48-bit· · ·xxxx

xxxxxxxxxxxxxxxx

xxxxxxxxx0111111

64-bit· · ·xxxx

xxxxxxxxxxxxxxxx

xnnnxxxxx1111111(80+16*nnn)-bit, nnn̸=111· · ·xxxx

xxxxxxxxxxxxxxxx

x111xxxxx1111111

Reserved for ≥192-bits

base+4base+2base

Figure 1.1: RISC-V instruction length encoding. Only the 16-bit and 32-bit encodings are considered frozen at this time.
Given the code size and energy savings of a compressed format, we wanted to build in support
for a compressed format to the ISA encoding scheme rather than adding this as an afterthought,
but to allow simpler implementations we didn’t want to make the compressed format mandatory.
We also wanted to optionally allow longer instructions to support experimentation and larger

Volume I: RISC-V Unprivileged ISA V20191213

9

instruction-set extensions. Although our encoding convention required a tighter encoding of thecore RISC-V ISA, this has several beneficial effects.
An implementation of the standard IMAFD ISA need only hold the most-significant 30 bits in
instruction caches (a 6.25% saving). On instruction cache refills, any instructions encounteredwith either low bit clear should be recoded into illegal 30-bit instructions before storing in thecache to preserve illegal instruction exception behavior.
Perhaps more importantly, by condensing our base ISA into a subset of the 32-bit instruction
word, we leave more space available for non-standard and custom extensions. In particular,
the base RV32I ISA uses less than 1/8 of the encoding space in the 32-bit instruction word.
As described in Chapter 26, an implementation that does not require support for the standard
compressed instruction extension can map 3 additional non-conforming 30-bit instruction spaces
into the 32-bit fixed-width format, while preserving support for standard ≥32-bit instruction-set
extensions. Further, if the implementation also does not need instructions >32-bits in length, it
can recover a further four major opcodes for non-conforming extensions.

Encodings with bits [15:0] all zeros are defined as illegal instructions. These instructions are considered to be of minimal length: 16 bits if any 16-bit instruction-set extension is present, otherwise
32 bits. The encoding with bits [ILEN-1:0] all ones is also illegal; this instruction is considered to
be ILEN bits long.
We consider it a feature that any length of instruction containing all zero bits is not legal, as
this quickly traps erroneous jumps into zeroed memory regions. Similarly, we also reserve theinstruction encoding containing all ones to be an illegal instruction, to catch the other common
pattern observed with unprogrammed non-volatile memory devices, disconnected memory buses,
or broken memory devices.
Software can rely on a naturally aligned 32-bit word containing zero to act as an illegal
instruction on all RISC-V implementations, to be used by software where an illegal instruction
is explicitly desired. Defining a corresponding known illegal value for all ones is more difficult
due to the variable-length encoding. Software cannot generally use the illegal value of ILEN bitsof all 1s, as software might not know ILEN for the eventual target machine (e.g., if software
is compiled into a standard binary library used by many different machines). Defining a 32-bit
word of all ones as illegal was also considered, as all machines must support a 32-bit instruction
size, but this requires the instruction-fetch unit on machines with ILEN>32 report an illegal
instruction exception rather than access fault when such an instruction borders a protection
boundary, complicating variable-instruction-length fetch and decode.

RISC-V base ISAs have either little-endian or big-endian memory systems, with the privilegedarchitecture further defining bi-endian operation. Instructions are stored in memory as a sequenceof 16-bit little-endian parcels, regardless of memory system endianness. Parcels forming one instruction are stored at increasing halfword addresses, with the lowest-addressed parcel holding thelowest-numbered bits in the instruction specification.
We originally chose little-endian byte ordering for the RISC-V memory system because littleendian systems are currently dominant commercially (all x86 systems; iOS, Android, and Windows for ARM). A minor point is that we have also found little-endian memory systems to be
more natural for hardware designers. However, certain application areas, such as IP networking,operate on big-endian data structures, and certain legacy code bases have been built assuming
big-endian processors, so we have defined big-endian and bi-endian variants of RISC-V.
We have to fix the order in which instruction parcels are stored in memory, independentof memory system endianness, to ensure that the length-encoding bits always appear first in
halfword address order. This allows the length of a variable-length instruction to be quickly

10Volume I: RISC-V Unprivileged ISA V20191213
determined by an instruction-fetch unit by examining only the first few bits of the first 16-bit
instruction parcel.
We further make the instruction parcels themselves little-endian to decouple the instruction
encoding from the memory system endianness altogether. This design benefits both softwaretooling and bi-endian hardware. Otherwise, for instance, a RISC-V assembler or disassembler
would always need to know the intended active endianness, despite that in bi-endian systems, theendianness mode might change dynamically during execution. In contrast, by giving instructions
a fixed endianness, it is sometimes possible for carefully written software to be endiannessagnostic even in binary form, much like position-independent code.
The choice to have instructions be only little-endian does have consequences, however, for
RISC-V software that encodes or decodes machine instructions. Big-endian JIT compilers, forexample, must swap the byte order when storing to instruction memory.
Once we had decided to fix on a little-endian instruction encoding, this naturally led toplacing the length-encoding bits in the LSB positions of the instruction format to avoid breaking
up opcode fields.

1.6

Exceptions, Traps, and Interrupts

We use the term exception to refer to an unusual condition occurring at run time associated withan instruction in the current RISC-V hart. We use the term interrupt to refer to an external
asynchronous event that may cause a RISC-V hart to experience an unexpected transfer of control.
We use the term trap to refer to the transfer of control to a trap handler caused by either an
exception or an interrupt.
The instruction descriptions in following chapters describe conditions that can raise an exception
during execution. The general behavior of most RISC-V EEIs is that a trap to some handler occurs
when an exception is signaled on an instruction (except for floating-point exceptions, which, inthe standard floating-point extensions, do not cause traps). The manner in which interrupts are
generated, routed to, and enabled by a hart depends on the EEI.
Our use of “exception” and “trap” is compatible with that in the IEEE-754 floating-point standard.

How traps are handled and made visible to software running on the hart depends on the enclosing
execution environment. From the perspective of software running inside an execution environment,
traps encountered by a hart at runtime can have four different effects:
Contained Trap: The trap is visible to, and handled by, software running inside the execution
environment. For example, in an EEI providing both supervisor and user mode on harts,
an ECALL by a user-mode hart will generally result in a transfer of control to a supervisormode handler running on the same hart. Similarly, in the same environment, when a hart isinterrupted, an interrupt handler will be run in supervisor mode on the hart.
Requested Trap: The trap is a synchronous exception that is an explicit call to the execution
environment requesting an action on behalf of software inside the execution environment. An
example is a system call. In this case, execution may or may not resume on the hart after
the requested action is taken by the execution environment. For example, a system call could
remove the hart or cause an orderly termination of the entire execution environment.

Volume I: RISC-V Unprivileged ISA V20191213

11

Invisible Trap: The trap is handled transparently by the execution environment and execution
resumes normally after the trap is handled. Examples include emulating missing instructions,handling non-resident page faults in a demand-paged virtual-memory system, or handlingdevice interrupts for a different job in a multiprogrammed machine. In these cases, thesoftware running inside the execution environment is not aware of the trap (we ignore timing
effects in these definitions).
Fatal Trap: The trap represents a fatal failure and causes the execution environment to terminate
execution. Examples include failing a virtual-memory page-protection check or allowing awatchdog timer to expire. Each EEI should define how execution is terminated and reported
to an external environment.
The following table shows the characteristics of each kind of trap:

Execution terminates?
Software is oblivious?
Handled by environment?

Contained
N
N
N

Requested
N1
N
Y

Invisible
N
Y
Y

Fatal
Y
Y2
Y

Table 1.1: Characteristics of traps. Notes: 1) termination may be requested; 2) imprecise fatal
traps might be observable by software.
The EEI defines for each trap whether it is handled precisely, though the recommendation is tomaintain preciseness where possible. Contained and requested traps can be observed to be imprecise
by software inside the execution environment. Invisible traps, by definition, cannot be observed to
be precise or imprecise by software running inside the execution environment. Fatal traps can beobserved to be imprecise by software running inside the execution environment, if known-errorful
instructions do not cause immediate termination.
Because this document describes unprivileged instructions, traps are rarely mentioned. Architectural means to handle contained traps are defined in the privileged architecture manual, along withother features to support richer EEIs. Unprivileged instructions that are defined solely to cause
requested traps are documented here. Invisible traps are, by their nature, out of scope for thisdocument. Instruction encodings that are not defined here and not defined by some other means
may cause a fatal trap.

1.7

UNSPECIFIED Behaviors and Values

The architecture fully describes what implementations must do and any constraints on what they
may do. In cases where the architecture intentionally does not constrain implementations, the term
unspecified is explicitly used.
The term unspecified refers to a behavior or value that is intentionally unconstrained. The
definition of these behaviors or values is open to extensions, platform standards, or implementations.
Extensions, platform standards, or implementation documentation may provide normative content
to further constrain cases that the base architecture defines as unspecified.

12

Volume I: RISC-V Unprivileged ISA V20191213

Like the base architecture, extensions should fully describe allowable behavior and values anduse the term unspecified for cases that are intentionally unconstrained. These cases may beconstrained or defined by other extensions, platform standards, or implementations.

Chapter 2

RV32I Base Integer Instruction Set,
Version 2.1
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 always traps and might be able to implement the FENCE instruction as a NOP, reducing baseinstruction 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.
Most of the commentary for RV32I also applies to the RV64I base.

2.1

Programmers’ Model for Base Integer ISA

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.
There is one additional unprivileged register: the program counter pc holds the address of thecurrent instruction.

13

14

Volume I: RISC-V Unprivileged ISA V20191213
XLEN-10x0 / 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-10

pc
XLEN

Figure 2.1: RISC-V base unprivileged integer register state.

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, thestandard software calling convention uses register x1 to hold the return address for a call, withregister x5 available as an alternate link register. The standard calling convention uses registerx2 as the stack pointer.
Hardware might choose to accelerate function calls and returns that use x1 or x5. See thedescriptions of the JAL and JALR instructions.
The optional compressed 16-bit instruction format is designed around the assumption thatx1 is the return address register and x2 is the stack pointer. Software using other conventions
will operate correctly but may have greater code size.
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

Volume I: RISC-V Unprivileged ISA V20191213

15

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. Dynamic register usage tends to be dominated by a few frequently accessed registers, and regfile implementations can be optimized to reduce access energy for the frequently accessed registers [20].
The optional compressed 16-bit instruction format mostly only accesses 8 registers and hence canprovide 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).

2.2

Base Instruction Formats

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.

The behavior upon decoding a reserved instruction is unspecified.
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 extensions.

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 particular, the sign bit for all immediates is always in bit 31 of the instruction to speed sign-extension
circuitry.
Decoding register specifiers is usually on the critical paths in implementations, and so the instruction 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 [11]).

16

Volume I: RISC-V Unprivileged ISA V20191213

31

25 24

funct720 19

rs2

imm[11:0]
imm[11:5]

rs2

15 14

12 11

7 6

0

rs1

funct3rd

opcodeR-typers1funct3rd

opcodeI-typers1funct3

imm[4:0]

opcodeS-typerd

opcodeU-typeimm[31:12]

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.
In practice, most immediates are either small or require all XLEN bits. We chose an asymmetric immediate split (12 bits in regular instructions plus a special load-upper-immediate instruction 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.

2.3

Immediate Encoding Variants

There are a further two variants of the instruction formats (B/J) based on the handling of immediates, as shown in Figure 2.3.
31

30

25 24

funct7

21

20

rs2

imm[12]

imm[10:5]

15 14

imm[10:1]

8

7

6

0

funct3rd

opcode R-typers1

funct3rd

opcode I-type

rs2

rs1

funct3

imm[4:0]

opcode S-type

rs2

rs1

funct3

imm[31:12]
imm[20]

12 11

rs1

imm[11:0]
imm[11:5]

19

imm[11]

imm[19:12]

imm[4:1] imm[11] opcode B-typerd

opcode U-typerd

opcode J-type

Figure 2.3: RISC-V base instruction formats showing immediate variants.
The only difference between the S and B formats is that the 12-bit immediate field is used to encode
branch offsets in multiples of 2 in the B format. Instead of shifting all bits in the instruction-encoded
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.

Volume I: RISC-V Unprivileged ISA V20191213

17

Similarly, the only difference 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 andwith 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

11

10

5

4

1

0

— inst[31] —inst[30:25] inst[24:21] inst[20] I-immediate— inst[31] —inst[30:25]

inst[11:8]

inst[7]

S-immediate

inst[30:25]

inst[11:8]

0

B-immediate— inst[31] —inst[31]

12

inst[30:20]— inst[31] —inst[7]
inst[19:12]
inst[19:12]—0—
inst[20] inst[30:25] inst[24:21]

U-immediate
0J-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 jumpcalculations and so would not benefit from keeping the location of immediate bits constant acrosstypes 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 hardware 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 somesmall additional overhead, but the most common short forward branches have straightforward
immediate encodings.

2.4

Integer Computational Instructions

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 isregister rd for both register-immediate and register-register instructions. No integer computational
instructions cause arithmetic exceptions.
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

18

Volume I: RISC-V Unprivileged ISA V20191213
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 thecommon 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 theother 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.

Integer Register-Immediate Instructions
31

20 19

imm[11:0]
12
I-immediate[11:0]
I-immediate[11:0]

15 14

rs1
5
src
src

12 11

funct33
ADDI/SLTI[U]
ANDI/ORI/XORI

7 6

rd
5
dest
dest

0

opcode7
OP-IMM
OP-IMM

ADDI adds the sign-extended 12-bit immediate to register rs1. Arithmetic overflow is ignored andthe result is simply the low XLEN bits of the result. ADDI rd, rs1, 0 is used to implement the MVrd, rs1 assembler pseudoinstruction.
SLTI (set less than immediate) places the value 1 in register rd if register rs1 is less than the signextended immediate when both are treated as signed numbers, else 0 is written to rd. SLTIU issimilar 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

imm[11:5]
70000000
0000000
0100000

20 19

imm[4:0]
5
shamt[4:0]
shamt[4:0]
shamt[4:0]

15 14

rs1
5
src
src
src

12 11

funct3
3
SLLI
SRLI
SRAI

7 6

rd
5
dest
dest
dest

0

opcode7
OP-IMM
OP-IMM
OP-IMM

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 rightshift type is encoded in bit 30. SLLI is a logical left shift (zeros are shifted into the lower bits);

Volume I: RISC-V Unprivileged ISA V20191213

19

SRLI is a logical right shift (zeros are shifted into the upper bits); and SRAI is an arithmetic rightshift (the original sign bit is copied into the vacated upper bits).
31

12 11

imm[31:12]
20
U-immediate[31:12]
U-immediate[31:12]

7 6

0

rd
5
dest
dest

opcode7
LUI
AUIPC

LUI (load upper immediate) is used to build 32-bit constants and uses the U-type format. LUIplaces the U-immediate value in the top 20 bits of 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-typeformat. AUIPC forms a 32-bit offset from the 20-bit U-immediate, filling in the lowest 12 bits withzeros, adds this offset to the address of the AUIPC instruction, then places the result in registerrd.
The AUIPC instruction supports two-instruction sequences to access arbitrary offsets from thePC 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 offset 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.

Integer Register-Register Operations
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 thetype of operation.
31

25 24

funct770000000
0000000
0000000
0100000

20 19

rs2
5
src2
src2
src2
src2

15 14

rs1
5
src1
src1
src1
src1

12 11

funct3
3
ADD/SLT/SLTU
AND/OR/XOR
SLL/SRL
SUB/SRA

7 6

rd
5
dest
dest
dest
dest

0

opcode
7
OP
OP
OP
OP

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,20

Volume I: RISC-V Unprivileged ISA V20191213

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 inregister rs1 by the shift amount held in the lower 5 bits of register rs2.

NOP Instruction
31

20 19

imm[11:0]
12
0

15 14

rs1
5
0

12 11

funct3
3
ADDI

7 6

rd
5
0

0

opcode7
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 encodea 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 asuperscalar design as adds are the most common operation. In particular, address-generation
functional units can execute ADDI using the same hardware needed for base+offset address
calculations, while register-register ADD or logical/shift operations require additional hardware.

2.5

Control Transfer Instructions

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 asigned offset in multiples of 2 bytes. The offset is sign-extended and added to the address of thejump instruction to form the jump target address. Jumps can therefore target a ±1 MiB range.
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 registerx5 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 different than the regular link register.

Volume I: RISC-V Unprivileged ISA V20191213

21

Plain unconditional jumps (assembler pseudoinstruction J) are encoded as a JAL with rd=x0.
31

imm[20]
1

30

21

20

19

imm[10:1]
imm[11]10
1offset[20:1]

12 11

imm[19:12]
8

7 6

rd
5
dest

0

opcode
7JAL

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

imm[11:0]
12
offset[11:0]

15 14

rs1
5
base

12 11

funct3
3
0

7 6

rd
5
dest

0

opcode7
JALR

The unconditional jump instructions all use PC-relative addressing to help support positionindependent code. The JALR instruction was defined to enable a two-instruction sequence tojump anywhere in a 32-bit absolute address range. A LUI instruction can first load rs1 with theupper 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 subroutine 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 thetarget address is not aligned to a four-byte boundary.
Instruction-address-misaligned exceptions are not possible on machines that support extensions
with 16-bit aligned instructions, such as the compressed instruction-set extension, C.

Return-address prediction stacks are a common feature of high-performance instruction-fetch units,
but require accurate detection of instructions used for procedure calls and returns to be effective.
For RISC-V, hints as to the instructions’ usage are encoded implicitly via the register numbers
used. A JAL instruction should push the return address onto a return-address stack (RAS) only
when rd=x1/x5. JALR instructions should push/pop a RAS as shown in the Table 2.1.
Some other ISAs added explicit hint bits to their indirect-jump instructions to guide returnaddress stack manipulation. We use implicit hinting tied to register numbers and the calling
convention to reduce the encoding space used for these hints.

22

Volume I: RISC-V Unprivileged ISA V20191213
rd
!link
!link
link
link
link

rs1
!link
link
!link
link
link

rs1=rd0
1

RAS action
none
pop
push
pop, then push
push

Table 2.1: Return-address stack prediction hints encoded in register specifiers used in the instruction. In the above, link is true when the register is either x1 or x5.
When two different 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 register (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
offsets in multiples of 2 bytes. The offset is sign-extended and added to the address of the branch
instruction to give the target address. The conditional branch range is ±4 KiB.
3130

imm[12] imm[10:5]
1
6
offset[12|10:5]
offset[12|10:5]
offset[12|10:5]

25 24

rs2
5
src2
src2
src2

20 19

rs1
5
src1
src1
src1

15 14

12 11

funct3
3
BEQ/BNEBLT[U]BGE[U]

8

7

imm[4:1]
imm[11]4
1
offset[11|4:1]
offset[11|4:1]
offset[11|4:1]

6

0

opcode7
BRANCH
BRANCH
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 greaterthan 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.

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 areencountered. 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 alwaystrue condition. RISC-V jumps are also PC-relative and support a much wider offset range thanbranches, and will not pollute conditional-branch prediction tables.

Volume I: RISC-V Unprivileged ISA V20191213

23

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 conditioncode 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 instructionis 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 relativelyrare.
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 andsoftware profiling for best results, and can result in poor performance if production runs do notmatch profiling runs.
We considered but did not include conditional moves or predicated instructions, which caneffectively 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, additional 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 microarchitectures, adding an implicit third source operand due to the need to copy the original value of thedestination 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 resultin 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 [6, 10, 9] and have been implemented in commercial processors [17].
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 [17].

The conditional branch instructions will generate an instruction-address-misaligned exception if thetarget address is not aligned to a four-byte boundary and the branch condition evaluates to true.
If the branch condition evaluates to false, the instruction-address-misaligned exception will not beraised.
Instruction-address-misaligned exceptions are not possible on machines that support extensions
with 16-bit aligned instructions, such as the compressed instruction-set extension, C.

24

Volume I: RISC-V Unprivileged ISA V20191213

2.6

Load and Store Instructions

RV32I is a load-store architecture, where only load and store instructions access memory andarithmetic instructions only operate on CPU registers. RV32I provides a 32-bit address space thatis byte-addressed. The EEI will define what portions of the address space are legal to access withwhich 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 effects even though
the load value is discarded.
The EEI will define whether the memory system is little-endian or big-endian. In RISC-V, endianness is byte-address invariant.
In a system for which endianness is byte-address invariant, the following property holds: if abyte 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 theirsignificance. Loads similarly transfer the contents of the lesser memory byte addresses to theless-significant register bytes.
In a big-endian configuration, multibyte stores write the most-significant register byte at thelowest memory byte address, followed by the other register bytes in descending order of theirsignificance. Loads similarly transfer the contents of the greater memory byte addresses to theless-significant register bytes.
31

20 19

imm[11:0]
12
offset[11:0]

31

rs1
5
base

25 24

imm[11:5]
7
offset[11:5]

15 14

20 19

rs2
5
src

funct3
3
width

15 14

rs1
5
base

12 11

7 6

rd
5
dest

12 11

funct33
width

imm[4:0]
5
offset[4:0]0opcode
7
LOAD

7 6

0

opcode7
STORE

Load and store instructions transfer a value between the registers and memory. Loads are encodedin the I-type format and stores are S-type. The effective address is obtained by adding register rs1
to the sign-extended 12-bit offset. Loads copy a value from memory to register rd. Stores copy thevalue 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 thenzero 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 effective addresses are naturally aligned shall not raise
an address-misaligned exception. Loads and stores where the effective address is not naturally

Volume I: RISC-V Unprivileged ISA V20191213

25aligned to the referenced datatype (i.e., on a four-byte boundary for 32-bit accesses, and a two-byteboundary for 16-bit accesses) have behavior dependent on the EEI.
An EEI may guarantee that misaligned loads and stores are fully supported, and so the software running 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 andinvisible 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 misalignment, an access 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 effects. 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 runninginside 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 theregular 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 offset 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 formsof 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). Furthermore, 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.
We do not mandate atomicity for misaligned accesses so execution environment implementations can use an invisible machine trap and a software handler to handle some or all misaligned
accesses. If hardware misaligned support is provided, software can exploit this by simply using
regular load and store instructions. Hardware can then automatically optimize accesses depending on whether runtime addresses are aligned.

26

Volume I: RISC-V Unprivileged ISA V20191213

2.7

Memory Ordering Instructions

31

28 27

fm
4
FM

PI
1

26

25

24

23

22

21

20

PO PR PW1
11
predecessor

SI
1

SO SR SW111successor

19

rs1
5
0

15 14

12 11

funct3
3
FENCE

7 6

rd
5
0

0

opcode7
MISC-MEM

The FENCE instruction is used to order device I/O and memory accesses as viewed by other RISCV 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 combinationof 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 anddevice output operations respectively rather than memory reads and writes. For example, memorymapped 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.
fm field
0000

Mnemonic
none

1000

TSO
other

Meaning
Normal Fence
With FENCE RW,RW: exclude write-to-read ordering
Otherwise: Reserved for future use.
Reserved for future use.

Table 2.2: Fence mode encoding.
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, predecessor=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 allstore 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 andtreat 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 infuture extensions. For forward compatibility, base implementations shall ignore these fields, andstandard software shall zero these fields. Likewise, many fm and predecessor/successor set settingsin Table 2.2 are also reserved for future use. Base implementations shall treat all such reserved

Volume I: RISC-V Unprivileged ISA V20191213

27

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 implementations and from likely future coprocessor or accelerator extensions. We separate out I/O orderingfrom memory R/W ordering to avoid unnecessary serialization within a device-driver hart andalso 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.

2.8

Environment Call and Breakpoints

SYSTEM instructions are used to access system functionality that might require privileged access and are encoded using the I-type instruction format. These can be divided into two mainclasses: those that atomically read-modify-write control and status registers (CSRs), and all otherpotentially privileged instructions. CSR instructions are described in Chapter 9, and the baseunprivileged instructions are described in the following section.
The SYSTEM instructions are defined to allow simpler implementations to always trap to asingle software trap handler. More sophisticated implementations might execute more of eachsystem instruction in hardware.

31

20 19

funct1212ECALL
EBREAK

15 14

rs1
5
0
0

12 11

funct3
3
PRIV
PRIV

7 6

rd
5
0
0

0

opcode7
SYSTEMSYSTEM

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.
The EBREAK instruction is used to return control to a debugging environment.
ECALL and EBREAK were previously named SCALL and SBREAK. The instructions havethe same functionality and encoding, but were renamed to reflect that they can be used moregenerally 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 fallback 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 includes a debugger that can provide services over an alternate system call interface built aroundthe EBREAK instruction. Because the RISC-V base ISA does not provide more than one

28

Volume I: RISC-V Unprivileged ISA V20191213
EBREAK instruction, RISC-V semihosting uses a special sequence of instructions to distinguish a semihosting EBREAK from a debugger inserted EBREAK.
slli x0, x0, 0x1f
ebreaksrai x0, x0, 7# Entry NOP# Break to debugger# NOP encoding the semihosting call number 7

Note that these three instructions must be 32-bit-wide instructions, i.e., they mustn’t be among
the compressed 16-bit instructions described in Chapter 16.
The shift NOP instructions are still considered available for use as HINTS.
Semihosting is a form of service call and would be more naturally encoded as an ECALL
using an existing ABI, but this would require the debugger to be able to intercept ECALLs, which
is a newer addition to the debug standard. We intend to move over to using ECALLs with astandard ABI, in which case, semihosting can share a service ABI with an existing standard.
We note that ARM processors have also moved to using SVC instead of BKPT for semihosting calls in newer designs.

2.9

HINT Instructions

RV32I reserves a large encoding space for HINT instructions, which are usually used to communicate 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. Implementations are always allowed to ignore the encoded hints.
This HINT encoding has been chosen so that simple implementations can ignore HINTs altogether, and instead execute a HINT as a regular computational instruction that happens not tomutate the architectural state. For example, ADD is a HINT if the destination register is x0; thefive-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 effect.

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 reserved 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-schedulinghints, security tags, and instrumentation flags for simulation/emulation.

Volume I: RISC-V Unprivileged ISA V20191213

Instruction
LUI
AUIPC
ADDI
ANDI
ORI
XORI
ADD
SUB
AND
OR
XOR
SLL
SRL
SRA
FENCE
SLTI
SLTIU
SLLI
SRLI
SRAI
SLT
SLTU

Constraints
rd=x0
rd=x0
rd=x0, and either
rs1̸=x0 or imm̸=0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
pred=0 or succ=0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0

Code Points
220
220

29

Purpose217 − 1
217
217
217
210
210
210
210
210
210
210
210
5
2 −1
217
217
210
210
210
210
210

Reserved for future standard use

Reserved for custom use

Table 2.3: RV32I HINT instructions.

30

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 3“Zifencei” Instruction-Fetch Fence,
Version 2.0
This chapter defines the “Zifencei” extension, which includes the FENCE.I instruction that provides
explicit synchronization between writes to instruction memory and instruction fetches on the same
hart. Currently, this instruction is the only standard mechanism to ensure that stores visible to a
hart will also be visible to its instruction fetches.
We considered but did not include a “store instruction word” instruction (as in MAJC [19]). JIT
compilers may generate a large trace of instructions before a single FENCE.I, and amortize any
instruction cache snooping/invalidation overhead by writing translated instructions to memory
regions that are known not to reside in the I-cache.
The FENCE.I instruction was designed to support a wide variety of implementations. A simple implementation can flush the local instruction cache and the instruction pipeline when the
FENCE.I is executed. A more complex implementation might snoop the instruction (data) cacheon every data (instruction) cache miss, or use an inclusive unified private L2 cache to invalidatelines from the primary instruction cache when they are being written by a local store instruction.
If instruction and data caches are kept coherent in this way, or if the memory system consistsof only uncached RAMs, then just the fetch pipeline needs to be flushed at a FENCE.I.
The FENCE.I instruction was previously part of the base I instruction set. Two main issues
are driving moving this out of the mandatory base, although at time of writing it is still the only
standard method for maintaining instruction-fetch coherence.
First, it has been recognized that on some systems, FENCE.I will be expensive to implement
and alternate mechanisms are being discussed in the memory model task group. In particular,
for designs that have an incoherent instruction cache and an incoherent data cache, or where
the instruction cache refill does not snoop a coherent data cache, both caches must be completely
flushed when a FENCE.I instruction is encountered. This problem is exacerbated when there are
multiple levels of I and D cache in front of a unified cache or outer memory system.
Second, the instruction is not powerful enough to make available at user level in a Unix-like
operating system environment. The FENCE.I only synchronizes the local hart, and the OS canreschedule the user hart to a different physical hart after the FENCE.I. This would require the
OS to execute an additional FENCE.I as part of every context migration. For this reason, thestandard Linux ABI has removed FENCE.I from user-level and now requires a system call tomaintain instruction-fetch coherence, which allows the OS to minimize the number of FENCE.I

31

32

Volume I: RISC-V Unprivileged ISA V20191213
executions required on current systems and provides forward-compatibility with future improved
instruction-fetch coherence mechanisms.
Future approaches to instruction-fetch coherence under discussion include providing more
restricted versions of FENCE.I that only target a given address specified in rs1, and/or allowing
software to use an ABI that relies on machine-mode cache-maintenance operations.

31

20 19

imm[11:0]
12
0

15 14

rs1
5
0

12 11

funct3
3
FENCE.I

7 6

rd
5
0

0

opcode7
MISC-MEM

The FENCE.I instruction is used to synchronize the instruction and data streams. RISC-V does
not guarantee that stores to instruction memory will be made visible to instruction fetches on a
RISC-V hart until that hart executes a FENCE.I instruction. A FENCE.I instruction ensures thata subsequent instruction fetch on a RISC-V hart will see any previous data stores already visible tothe same RISC-V hart. FENCE.I does not ensure that other RISC-V harts’ instruction fetches willobserve the local hart’s stores in a multiprocessor system. To make a store to instruction memory
visible to all RISC-V harts, the writing hart has to execute a data FENCE before requesting that
all remote RISC-V harts execute a FENCE.I.
The unused fields in the FENCE.I instruction, imm[11:0], rs1, and rd, are reserved for finer-grain
fences in future extensions. For forward compatibility, base implementations shall ignore thesefields, and standard software shall zero these fields.
Because FENCE.I only orders stores with a hart’s own instruction fetches, application codeshould only rely upon FENCE.I if the application thread will not be migrated to a different hart.
The EEI can provide mechanisms for efficient multiprocessor instruction-stream synchronization.

Chapter 4

RV32E Base Integer Instruction Set,
Version 1.9
This chapter describes a draft proposal for the RV32E base integer instruction set, which is areduced version of RV32I designed for embedded systems. The only change is to reduce the numberof integer registers to 16. This chapter only outlines the differences between RV32E and RV32I,
and so should be read after Chapter 2.
RV32E was designed to provide an even smaller base core for embedded microcontrollers. Although we had mentioned this possibility in version 2.0 of this document, we initially resisted
defining this subset. However, given the demand for the smallest possible 32-bit microcontroller,
and in the interests of preempting fragmentation in this space, we have now defined RV32E asa fourth standard base ISA in addition to RV32I, RV64I, and RV128I. There is also interest in
defining an RV64E to reduce context state for highly threaded 64-bit processors.

4.1

RV32E Programmers’ Model

RV32E reduces the integer register count to 16 general-purpose registers, (x0–x15), where x0 is a
dedicated zero register.
We have found that in the small RV32I core designs, the upper 16 registers consume around one
quarter of the total area of the core excluding memories, thus their removal saves around 25%
core area with a corresponding core power reduction.
This change requires a different calling convention and ABI. In particular, RV32E is only usedwith a soft-float calling convention. A new embedded ABI is under consideration that would
work across RV32E and RV32I.

33

34

4.2

Volume I: RISC-V Unprivileged ISA V20191213

RV32E Instruction Set

RV32E uses the same instruction-set encoding as RV32I, except that only registers x0–x15 areprovided. Any future standard extensions will not make use of the instruction bits freed up by the
reduced register-specifier fields and so these are available for custom extensions.
RV32E can be combined with all current standard extensions. Defining the F, D, and Q extensions as having a 16-entry floating point register file when combined with RV32E was considered
but decided against. To support systems with reduced floating-point register state, we intend
to define a “Zfinx” extension that makes floating-point computations use the integer registers,
removing the floating-point loads, stores, and moves between floating point and integer registers.

Chapter 5

RV64I Base Integer Instruction Set,
Version 2.1
This chapter describes the RV64I base integer instruction set, which builds upon the RV32I variant
described in Chapter 2. This chapter presents only the differences with RV32I, so should be readin conjunction with the earlier chapter.

5.1

Register StateRV64I widens the integer registers and supported user address space to 64 bits (XLEN=64 in
Figure 2.1).

5.2

Integer Computational Instructions

Most integer computational instructions operate on XLEN-bit values. Additional instruction variants are provided to manipulate 32-bit values in RV64I, indicated by a ‘W’ suffix to the opcode.
These “*W” instructions ignore the upper 32 bits of their inputs and always produce 32-bit signed
values, i.e. bits XLEN-1 through 31 are equal.
The compiler and calling convention maintain an invariant that all 32-bit values are held in asign-extended format in 64-bit registers. Even 32-bit unsigned integers extend bit 31 into bits 63
through 32. Consequently, conversion between unsigned and signed 32-bit integers is a no-op,
as is conversion from a signed 32-bit integer to a signed 64-bit integer. Existing 64-bit wide
SLTU and unsigned branch compares still operate correctly on unsigned 32-bit integers under
this invariant. Similarly, existing 64-bit wide logical operations on 32-bit sign-extended integers
preserve the sign-extension property. A few new instructions (ADD[I]W/SUBW/SxxW) are
required for addition and shifts to ensure reasonable performance for 32-bit values.

35

36

Volume I: RISC-V Unprivileged ISA V20191213

Integer Register-Immediate Instructions
31

20 19

imm[11:0]
12
I-immediate[11:0]

15 14

rs1
5
src

12 11

funct3
3
ADDIW

7 6

rd
5
dest

0

opcode7
OP-IMM-32

ADDIW is an RV64I instruction that adds the sign-extended 12-bit immediate to register rs1
and produces the proper sign-extension of a 32-bit result in rd. Overflows are ignored and theresult is the low 32 bits of the result sign-extended to 64 bits. Note, ADDIW rd, rs1, 0 writes
the sign-extension of the lower 32 bits of register rs1 into register rd (assembler pseudoinstruction
SEXT.W).
31

26

imm[11:6]
600000000000001000000000000000001000025

24

imm[5]
1
shamt[5]shamt[5]shamt[5]
0
0
0

20 19

imm[4:0]
5
shamt[4:0]
shamt[4:0]
shamt[4:0]
shamt[4:0]
shamt[4:0]
shamt[4:0]

15 14

rs1
5
src
src
src
src
src
src

12 11

funct3
3
SLLI
SRLI
SRAI
SLLIW
SRLIW
SRAIW

7 6

rd
5
dest
dest
dest
dest
dest
dest

0

opcode7
OP-IMM
OP-IMM
OP-IMM
OP-IMM-32
OP-IMM-32
OP-IMM-32

Shifts by a constant are encoded as a specialization of the I-type format using the same instruction
opcode as RV32I. The operand to be shifted is in rs1, and the shift amount is encoded in the lower
6 bits of the I-immediate field for RV64I. The right shift type is encoded in bit 30. SLLI is alogical 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 thevacated upper bits).
SLLIW, SRLIW, and SRAIW are RV64I-only instructions that are analogously defined but operate
on 32-bit values and produce signed 32-bit results. SLLIW, SRLIW, and SRAIW encodings withimm[5] ̸= 0 are reserved.
Previously, SLLIW, SRLIW, and SRAIW with imm[5] ̸= 0 were defined to cause illegal instruction exceptions, whereas now they are marked as reserved. This is a backwards-compatiblechange.
31

12 11

imm[31:12]
20
U-immediate[31:12]
U-immediate[31:12]

7 6

rd
5
dest
dest

0

opcode7
LUI
AUIPC

LUI (load upper immediate) uses the same opcode as RV32I. LUI places the 20-bit U-immediate
into bits 31–12 of register rd and places zero in the lowest 12 bits. The 32-bit result is sign-extended
to 64 bits.

Volume I: RISC-V Unprivileged ISA V20191213

37

AUIPC (add upper immediate to pc) uses the same opcode as RV32I. AUIPC is used to build pcrelative addresses and uses the U-type format. AUIPC appends 12 low-order zero bits to the 20-bit
U-immediate, sign-extends the result to 64 bits, adds it to the address of the AUIPC instruction,then places the result in register rd.

Integer Register-Register Operations
31

25 24

funct770000000
0100000
0000000
0000000
0100000

20 19

rs2
5
src2
src2
src2
src2
src2

15 14

rs1
5
src1
src1
src1
src1
src1

12 11

7 6

funct3
3
SLL/SRLSRA
ADDW
SLLW/SRLW
SUBW/SRAW

rd
5
dest
dest
dest
dest
dest

0

opcode
7
OP
OP
OP-32
OP-32
OP-32

ADDW and SUBW are RV64I-only instructions that are defined analogously to ADD and SUB
but operate on 32-bit values and produce signed 32-bit results. Overflows are ignored, and the low
32-bits of the result is sign-extended to 64-bits and written to the destination register.
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 register rs2. In RV64I, only the low 6 bits of rs2 areconsidered for the shift amount.
SLLW, SRLW, and SRAW are RV64I-only instructions that are analogously defined but operate
on 32-bit values and produce signed 32-bit results. The shift amount is given by rs2[4:0].

5.3

Load and Store Instructions

RV64I extends the address space to 64 bits. The execution environment will define what portionsof the address space are legal to access.
31

20 19

imm[11:0]
12
offset[11:0]

31

25 24

imm[11:5]
7
offset[11:5]

15 14

rs1
5
base

20 19

rs2
5
src

12 11

funct3
3
width

15 14

rs1
5
base

7 6

rd
5
dest

12 11

funct33
width

0

opcode7
LOAD

7 6

imm[4:0]
5
offset[4:0]

The LD instruction loads a 64-bit value from memory into register rd for RV64I.

0

opcode
7
STORE

38

Volume I: RISC-V Unprivileged ISA V20191213

The LW instruction loads a 32-bit value from memory and sign-extends this to 64 bits before storing
it in register rd for RV64I. The LWU instruction, on the other hand, zero-extends the 32-bit value
from memory for RV64I. LH and LHU are defined analogously for 16-bit values, as are LB and
LBU for 8-bit values. The SD, SW, SH, and SB instructions store 64-bit, 32-bit, 16-bit, and 8-bit
values from the low bits of register rs2 to memory respectively.

5.4

HINT Instructions

All instructions that are microarchitectural HINTs in RV32I (see Section 2.9) are also HINTs in
RV64I. The additional computational instructions in RV64I expand both the standard and custom
HINT encoding spaces.
Table 5.1 lists all RV64I 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 reserved for custom HINTs:
no standard HINTs will ever be defined in this subspace.

Volume I: RISC-V Unprivileged ISA V20191213

Instruction
LUI
AUIPC
ADDI
ANDI
ORI
XORI
ADDIW
ADD
SUB
AND
OR
XOR
SLL
SRL
SRA
ADDW
SUBW
SLLW
SRLW
SRAW
FENCE
SLTI
SLTIU
SLLI
SRLI
SRAI
SLLIW
SRLIW
SRAIW
SLT
SLTU

Constraints
rd=x0
rd=x0
rd=x0, and either
rs1̸=x0 or imm̸=0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
pred=0 or succ=0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0
rd=x0

Code Points
220
220

39

Purpose217 − 1
217
217
217
217
210
210
210
210
210
210
210
210
210
210
210
210
210
5
2 −1
217
217
211
211
211
210
210
210
210
210

Reserved for future standard use

Reserved for custom use

Table 5.1: RV64I HINT instructions.

40

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 6

RV128I Base Integer Instruction Set,
Version 1.7“There is only one mistake that can be made in computer design that is difficult to recover from—not having enough address bits for memory addressing and memory management.” Bell and Strecker, ISCA-3, 1976.
This chapter describes RV128I, a variant of the RISC-V ISA supporting a flat 128-bit address space.
The variant is a straightforward extrapolation of the existing RV32I and RV64I designs.
The primary reason to extend integer register width is to support larger address spaces. It is
not clear when a flat address space larger than 64 bits will be required. At the time of writing,the fastest supercomputer in the world as measured by the Top500 benchmark had over 1 PB
of DRAM, and would require over 50 bits of address space if all the DRAM resided in a single
address space. Some warehouse-scale computers already contain even larger quantities of DRAM,
and new dense solid-state non-volatile memories and fast interconnect technologies might drive ademand for even larger memory spaces. Exascale systems research is targeting 100 PB memory
systems, which occupy 57 bits of address space. At historic rates of growth, it is possible that
greater than 64 bits of address space might be required before 2030.
History suggests that whenever it becomes clear that more than 64 bits of address space isneeded, architects will repeat intensive debates about alternatives to extending the address space,including segmentation, 96-bit address spaces, and software workarounds, until, finally, flat 128bit address spaces will be adopted as the simplest and best solution.
We have not frozen the RV128 spec at this time, as there might be need to evolve the design
based on actual usage of 128-bit address spaces.

RV128I builds upon RV64I in the same way RV64I builds upon RV32I, with integer registers
extended to 128 bits (i.e., XLEN=128). Most integer computational instructions are unchanged
as they are defined to operate on XLEN bits. The RV64I “*W” integer instructions that operate
on 32-bit values in the low bits of a register are retained but now sign extend their results frombit 31 to bit 127. A new set of “*D” integer instructions are added that operate on 64-bit values
held in the low bits of the 128-bit integer registers and sign extend their results from bit 63 to bit
127. The “*D” instructions consume two major opcodes (OP-IMM-64 and OP-64) in the standard
32-bit encoding.
41

42

Volume I: RISC-V Unprivileged ISA V20191213

To improve compatibility with RV64, in a reverse of how RV32 to RV64 was handled, we mightchange the decoding around to rename RV64I ADD as a 64-bit ADDD, and add a 128-bit ADDQin what was previously the OP-64 major opcode (now renamed the OP-128 major opcode).

Shifts by an immediate (SLLI/SRLI/SRAI) are now encoded using the low 7 bits of the I-immediate,and variable shifts (SLL/SRL/SRA) use the low 7 bits of the shift amount source register.
A LDU (load double unsigned) instruction is added using the existing LOAD major opcode, alongwith new LQ and SQ instructions to load and store quadword values. SQ is added to the STORE
major opcode, while LQ is added to the MISC-MEM major opcode.
The floating-point instruction set is unchanged, although the 128-bit Q floating-point extension can
now support FMV.X.Q and FMV.Q.X instructions, together with additional FCVT instructions toand from the T (128-bit) integer format.

Chapter 7“M” Standard Extension for Integer
Multiplication and Division, Version
2.0This chapter describes the standard integer multiplication and division instruction extension, whichis named “M” and contains instructions that multiply or divide values held in two integer registers.
We separate integer multiply and divide out from the base to simplify low-end implementations,or for applications where integer multiply and divide operations are either infrequent or better
handled in attached accelerators.

7.1

Multiplication Operations

31

25 24

funct7
7
MULDIV
MULDIVrs2
5
multiplier
multiplier

20 19

15 14

12 11

rs1
funct3rd5
3
5
multiplicand MUL/MULH[[S]U] dest
multiplicand
MULW
dest

7 6

0

opcode7
OP
OP-32

MUL performs an XLEN-bit×XLEN-bit multiplication of rs1 by rs2 and places the lower XLEN bitsin the destination register. MULH, MULHU, and MULHSU perform the same multiplication but return the upper XLEN bits of the full 2×XLEN-bit product, for signed×signed, unsigned×unsigned,
and signed rs1×unsigned rs2 multiplication, respectively. If both the high and low bits of the same
product are required, then the recommended code sequence is: MULH[[S]U] rdh, rs1, rs2; MULrdl, rs1, rs2 (source register specifiers must be in same order and rdh cannot be the same as rs1 or
rs2). Microarchitectures can then fuse these into a single multiply operation instead of performing
two separate multiplies.

43

44

Volume I: RISC-V Unprivileged ISA V20191213

MULHSU is used in multi-word signed multiplication to multiply the most-significant word of
the multiplicand (which contains the sign bit) with the less-significant words of the multiplier(which are unsigned).

MULW is an RV64 instruction that multiplies the lower 32 bits of the source registers, placing thesign-extension of the lower 32 bits of the result into the destination register.
In RV64, MUL can be used to obtain the upper 32 bits of the 64-bit product, but signed arguments
must be proper 32-bit signed values, whereas unsigned arguments must have their upper 32 bits
clear. If the arguments are not known to be sign- or zero-extended, an alternative is to shift botharguments left by 32 bits, then use MULH[[S]U].

7.2

Division Operations

31

25 24

funct7
7
MULDIV
MULDIV

20 19

rs2
5
divisordivisorrs1
5
dividend
dividend

15 14

12 11

funct3
3
DIV[U]/REM[U]
DIV[U]W/REM[U]W

7 6

rd
5
dest
dest

0

opcode7
OP
OP-32

DIV and DIVU perform an XLEN bits by XLEN bits signed and unsigned integer division of rs1 by
rs2, rounding towards zero. REM and REMU provide the remainder of the corresponding division
operation. For REM, the sign of the result equals the sign of the dividend.
For both signed and unsigned division, it holds that dividend = divisor × quotient + remainder.

If both the quotient and remainder are required from the same division, the recommended code
sequence is: DIV[U] rdq, rs1, rs2; REM[U] rdr, rs1, rs2 (rdq cannot be the same as rs1 or rs2).
Microarchitectures can then fuse these into a single divide operation instead of performing two
separate divides.
DIVW and DIVUW are RV64 instructions that divide the lower 32 bits of rs1 by the lower 32
bits of rs2, treating them as signed and unsigned integers respectively, placing the 32-bit quotientin rd, sign-extended to 64 bits. REMW and REMUW are RV64 instructions that provide thecorresponding signed and unsigned remainder operations respectively. Both REMW and REMUW
always sign-extend the 32-bit result to 64 bits, including on a divide by zero.
The semantics for division by zero and division overflow are summarized in Table 7.1. The quotientof division by zero has all bits set, and the remainder of division by zero equals the dividend. Signed
division overflow occurs only when the most-negative integer is divided by −1. The quotient of asigned division with overflow is equal to the dividend, and the remainder is zero. Unsigned division
overflow cannot occur.
We considered raising exceptions on integer divide by zero, with these exceptions causing a trap inmost execution environments. However, this would be the only arithmetic trap in the standard
ISA (floating-point exceptions set flags and write default values, but do not cause traps) andVolume I: RISC-V Unprivileged ISA V20191213
Condition
Division by zero
Overflow (signed only)

Dividendx−2L−1

Divisor
0−1

45
DIVU[W]
2L − 1–

REMU[W]x–

DIV[W]−1−2L−1

REM[W]
x0

Table 7.1: Semantics for division by zero and division overflow. L is the width of the operation inbits: XLEN for DIV[U] and REM[U], or 32 for DIV[U]W and REM[U]W.
would require language implementors to interact with the execution environment’s trap handlers
for this case. Further, where language standards mandate that a divide-by-zero exception mustcause an immediate control flow change, only a single branch instruction needs to be added toeach divide operation, and this branch instruction can be inserted after the divide and should
normally be very predictably not taken, adding little runtime overhead.
The value of all bits set is returned for both unsigned and signed divide by zero to simplify
the divider circuitry. The value of all 1s is both the natural value to return for unsigned divide,
representing the largest unsigned number, and also the natural result for simple unsigned divider
implementations. Signed division is often implemented using an unsigned division circuit andspecifying the same overflow result simplifies the hardware.

46

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 8“A” Standard Extension for Atomic
Instructions, Version 2.1
The standard atomic-instruction extension, named “A”, contains instructions that atomically
read-modify-write memory to support synchronization between multiple RISC-V harts runningin the same memory space. The two forms of atomic instruction provided are load-reserved/storeconditional instructions and atomic fetch-and-op memory instructions. Both types of atomic instruction support various memory consistency orderings including unordered, acquire, release, andsequentially consistent semantics. These instructions allow RISC-V to support the RCsc memory
consistency model [5].
After much debate, the language community and architecture community appear to have finallysettled on release consistency as the standard memory consistency model and so the RISC-V
atomic support is built around this model.

8.1

Specifying Ordering of Atomic Instructions

The base RISC-V ISA has a relaxed memory model, with the FENCE instruction used to impose
additional ordering constraints. The address space is divided by the execution environment intomemory and I/O domains, and the FENCE instruction provides options to order accesses to one
or both of these two address domains.
To provide more efficient support for release consistency [5], each atomic instruction has two bits,
aq and rl, used to specify additional memory ordering constraints as viewed by other RISC-V harts.
The bits order accesses to one of the two address domains, memory or I/O, depending on which
address domain the atomic instruction is accessing. No ordering constraint is implied to accesses
to the other domain, and a FENCE instruction should be used to order across both domains.
If both bits are clear, no additional ordering constraints are imposed on the atomic memory operation. If only the aq bit is set, the atomic memory operation is treated as an acquire access,i.e., no following memory operations on this RISC-V hart can be observed to take place before theacquire memory operation. If only the rl bit is set, the atomic memory operation is treated as a47

48

Volume I: RISC-V Unprivileged ISA V20191213

release access, i.e., the release memory operation cannot be observed to take place before any earlier
memory operations on this RISC-V hart. If both the aq and rl bits are set, the atomic memory
operation is sequentially consistent and cannot be observed to happen before any earlier memory
operations or after any later memory operations in the same RISC-V hart and to the same address
domain.

8.2

Load-Reserved/Store-Conditional Instructions

31

27

funct55LR.W/D
SC.W/D

26

25

aq
rl
1
1
ordering
ordering

24

20 19

rs2
5
0
src

15 14

rs1
5
addr
addr

12 11

funct3
3
width
width

7 6

rd
5
dest
dest

0

opcode7
AMO
AMO

Complex atomic memory operations on a single memory word or doubleword are performed with theload-reserved (LR) and store-conditional (SC) instructions. LR.W loads a word from the addressin rs1, places the sign-extended value in rd, and registers a reservation set—a set of bytes that
subsumes the bytes in the addressed word. SC.W conditionally writes a word in rs2 to the addressin rs1: the SC.W succeeds only if the reservation is still valid and the reservation set contains thebytes being written. If the SC.W succeeds, the instruction writes the word in rs2 to memory, andit writes zero to rd. If the SC.W fails, the instruction does not write to memory, and it writes anonzero value to rd. Regardless of success or failure, executing an SC.W instruction invalidates
any reservation held by this hart. LR.D and SC.D act analogously on doublewords and are only
available on RV64. For RV64, LR.W and SC.W sign-extend the value placed in rd.
Both compare-and-swap (CAS) and LR/SC can be used to build lock-free data structures. Afterextensive discussion, we opted for LR/SC for several reasons: 1) CAS suffers from the ABA
problem, which LR/SC avoids because it monitors all accesses to the address rather than only
checking for changes in the data value; 2) CAS would also require a new integer instruction format to support three source operands (address, compare value, swap value) as well as a different
memory system message format, which would complicate microarchitectures; 3) Furthermore,
to avoid the ABA problem, other systems provide a double-wide CAS (DW-CAS) to allow a
counter to be tested and incremented along with a data word. This requires reading five registers and writing two in one instruction, and also a new larger memory system message type,further complicating implementations; 4) LR/SC provides a more efficient implementation ofmany primitives as it only requires one load as opposed to two with CAS (one load before the
CAS instruction to obtain a value for speculative computation, then a second load as part of the
CAS instruction to check if value is unchanged before updating).
The main disadvantage of LR/SC over CAS is livelock, which we avoid, under certain circumstances, with an architected guarantee of eventual forward progress as described below. Another concern is whether the influence of the current x86 architecture, with its DW-CAS, willcomplicate porting of synchronization libraries and other software that assumes DW-CAS is thebasic machine primitive. A possible mitigating factor is the recent addition of transactional
memory instructions to x86, which might cause a move away from DW-CAS.
More generally, a multi-word atomic primitive is desirable, but there is still considerable
debate about what form this should take, and guaranteeing forward progress adds complexity toa system. Our current thoughts are to include a small limited-capacity transactional memory

Volume I: RISC-V Unprivileged ISA V20191213

49

buffer along the lines of the original transactional memory proposals as an optional standard
extension “T”.

The failure code with value 1 is reserved to encode an unspecified failure. Other failure codes arereserved at this time, and portable software should only assume the failure code will be non-zero.
We reserve a failure code of 1 to mean “unspecified” so that simple implementations may return
this value using the existing mux required for the SLT/SLTU instructions. More specific failure
codes might be defined in future versions or extensions to the ISA.

For LR and SC, the A extension requires that the address held in rs1 be naturally aligned to thesize of the operand (i.e., eight-byte aligned for 64-bit words and four-byte aligned for 32-bit words).
If the address is not naturally aligned, an address-misaligned exception or an access-fault exception
will be generated. The access-fault exception can be generated for a memory access that would
otherwise be able to complete except for the misalignment, if the misaligned access should not beemulated.
Emulating misaligned LR/SC sequences is impractical in most systems.
Misaligned LR/SC sequences also raise the possibility of accessing multiple reservation sets
at once, which present definitions do not provide for.

An implementation can register an arbitrarily large reservation set on each LR, provided the reservation set includes all bytes of the addressed data word or doubleword. An SC can only pair withthe most recent LR in program order. An SC may succeed only if no store from another hart to
the reservation set can be observed to have occurred between the LR and the SC, and if there isno other SC between the LR and itself in program order. An SC may succeed only if no write froma device other than a hart to the bytes accessed by the LR instruction can be observed to haveoccurred between the LR and SC. Note this LR might have had a different effective address anddata size, but reserved the SC’s address as part of the reservation set.
Following this model, in systems with memory translation, an SC is allowed to succeed if theearlier LR reserved the same location using an alias with a different virtual address, but is also
allowed to fail if the virtual address is different.
To accommodate legacy devices and buses, writes from devices other than RISC-V harts are only
required to invalidate reservations when they overlap the bytes accessed by the LR. These writes
are not required to invalidate the reservation when they access other bytes in the reservation set.

The SC must fail if the address is not within the reservation set of the most recent LR in program
order. The SC must fail if a store to the reservation set from another hart can be observed tooccur between the LR and SC. The SC must fail if a write from some other device to the bytes
accessed by the LR can be observed to occur between the LR and SC. (If such a device writes thereservation set but does not write the bytes accessed by the LR, the SC may or may not fail.) An
SC must fail if there is another SC (to any address) between the LR and the SC in program order.
The precise statement of the atomicity requirements for successful LR/SC sequences is defined by
the Atomicity Axiom in Section 14.1.
The platform should provide a means to determine the size and shape of the reservation set.

50

Volume I: RISC-V Unprivileged ISA V20191213
A platform specification may constrain the size and shape of the reservation set. For example,
the Unix platform is expected to require of main memory that the reservation set be of fixed size,
contiguous, naturally aligned, and no greater than the virtual memory page size.
A store-conditional instruction to a scratch word of memory should be used to forcibly invalidate
any existing load reservation:• during a preemptive context switch, and• if necessary when changing virtual to physical address mappings, such as when migrating
pages that might contain an active reservation.
The invalidation of a hart’s reservation when it executes an LR or SC imply that a hart can
only hold one reservation at a time, and that an SC can only pair with the most recent LR, andLR with the next following SC, in program order. This is a restriction to the Atomicity Axiom
in Section 14.1 that ensures software runs correctly on expected common implementations that
operate in this manner.

An SC instruction can never be observed by another RISC-V hart before the LR instruction that
established the reservation. The LR/SC sequence can be given acquire semantics by setting the aq
bit on the LR instruction. The LR/SC sequence can be given release semantics by setting the rl
bit on the SC instruction. Setting the aq bit on the LR instruction, and setting both the aq andthe rl bit on the SC instruction makes the LR/SC sequence sequentially consistent, meaning thatit cannot be reordered with earlier or later memory operations from the same hart.
If neither bit is set on both LR and SC, the LR/SC sequence can be observed to occur before orafter surrounding memory operations from the same RISC-V hart. This can be appropriate whenthe LR/SC sequence is used to implement a parallel reduction operation.
Software should not set the rl bit on an LR instruction unless the aq bit is also set, nor should
software set the aq bit on an SC instruction unless the rl bit is also set. LR.rl and SC.aq instructions
are not guaranteed to provide any stronger ordering than those with both bits clear, but may resultin lower performance.
# a0 holds address of memory location# a1 holds expected value# a2 holds desired value# a0 holds return value, 0 if successful, !0 otherwise
cas:lr.w t0, (a0)
# Load original value.
bne t0, a1, fail
# Doesn’t match, so fail.
sc.w t0, a2, (a0)# Try to update.
bnez t0, cas# Retry if store-conditional failed.
li a0, 0# Set return to success.
jr ra# Return.
fail:
li a0, 1# Set return to failure.
jr ra# Return.
Figure 8.1: Sample code for compare-and-swap function using LR/SC.

Volume I: RISC-V Unprivileged ISA V20191213

51

LR/SC can be used to construct lock-free data structures. An example using LR/SC to implement
a compare-and-swap function is shown in Figure 8.1. If inlined, compare-and-swap functionality
need only take four instructions.

8.3

Eventual Success of Store-Conditional Instructions

The standard A extension defines constrained LR/SC loops, which have the following properties:• The loop comprises only an LR/SC sequence and code to retry the sequence in the case of
failure, and must comprise at most 16 instructions placed sequentially in memory.
• An LR/SC sequence begins with an LR instruction and ends with an SC instruction. The
dynamic code executed between the LR and SC instructions can only contain instructions
from the base “I” instruction set, excluding loads, stores, backward jumps, taken backward
branches, JALR, FENCE, FENCE.I, and SYSTEM instructions. If the “C” extension is
supported, then compressed forms of the aforementioned “I” instructions are also permitted.
• The code to retry a failing LR/SC sequence can contain backwards jumps and/or branches
to repeat the LR/SC sequence, but otherwise has the same constraint as the code between
the LR and SC.
• The LR and SC addresses must lie within a memory region with the LR/SC eventuality
property. The execution environment is responsible for communicating which regions havethis property.
• The SC must be to the same effective address and of the same data size as the latest LR
executed by the same hart.
LR/SC sequences that do not lie within constrained LR/SC loops are unconstrained. Unconstrained
LR/SC sequences might succeed on some attempts on some implementations, but might neversucceed on other implementations.
We restricted the length of LR/SC loops to fit within 64 contiguous instruction bytes in the base
ISA to avoid undue restrictions on instruction cache and TLB size and associativity. Similarly, we disallowed other loads and stores within the loops to avoid restrictions on data-cacheassociativity in simple implementations that track the reservation within a private cache. The
restrictions on branches and jumps limit the time that can be spent in the sequence. Floatingpoint operations and integer multiply/divide were disallowed to simplify the operating system’semulation of these instructions on implementations lacking appropriate hardware support.
Software is not forbidden from using unconstrained LR/SC sequences, but portable softwaremust detect the case that the sequence repeatedly fails, then fall back to an alternate code sequencethat does not rely on an unconstrained LR/SC sequence. Implementations are permitted tounconditionally fail any unconstrained LR/SC sequence.

If a hart H enters a constrained LR/SC loop, the execution environment must guarantee that oneof the following events eventually occurs:• H or some other hart executes a successful SC to the reservation set of the LR instruction in
H’s constrained LR/SC loops.
• Some other hart executes an unconditional store or AMO instruction to the reservation set of
the LR instruction in H’s constrained LR/SC loop, or some other device in the system writes
to that reservation set.

52

Volume I: RISC-V Unprivileged ISA V20191213• H executes a branch or jump that exits the constrained LR/SC loop.
• H traps.

Note that these definitions permit an implementation to fail an SC instruction occasionally for
any reason, provided the aforementioned guarantee is not violated.
As a consequence of the eventuality guarantee, if some harts in an execution environment are
executing constrained LR/SC loops, and no other harts or devices in the execution environment
execute an unconditional store or AMO to that reservation set, then at least one hart will
eventually exit its constrained LR/SC loop. By contrast, if other harts or devices continue towrite to that reservation set, it is not guaranteed that any hart will exit its LR/SC loop.
Loads and load-reserved instructions do not by themselves impede the progress of other harts’
LR/SC sequences. We note this constraint implies, among other things, that loads and loadreserved instructions executed by other harts (possibly within the same core) cannot impede
LR/SC progress indefinitely. For example, cache evictions caused by another hart sharing thecache cannot impede LR/SC progress indefinitely. Typically, this implies reservations are tracked
independently of evictions from any shared cache. Similarly, cache misses caused by speculative
execution within a hart cannot impede LR/SC progress indefinitely.
These definitions admit the possibility that SC instructions may spuriously fail for implementation reasons, provided progress is eventually made.
One advantage of CAS is that it guarantees that some hart eventually makes progress, whereasan LR/SC atomic sequence could livelock indefinitely on some systems. To avoid this concern,
we added an architectural guarantee of livelock freedom for certain LR/SC sequences.
Earlier versions of this specification imposed a stronger starvation-freedom guarantee. However, the weaker livelock-freedom guarantee is sufficient to implement the C11 and C++11 languages, and is substantially easier to provide in some microarchitectural styles.

8.4
31

Atomic Memory Operations
27

26

25

funct5aqrl
5
1
1
AMOSWAP.W/D ordering
AMOADD.W/D ordering
AMOAND.W/D ordering
AMOOR.W/D ordering
AMOXOR.W/D ordering
AMOMAX[U].W/D ordering
AMOMIN[U].W/D ordering

24

20 19

rs2
5
src
src
src
src
src
src
src

15 14

rs1
5
addr
addr
addr
addr
addr
addr
addr

12 11

funct3
3
width
width
width
width
width
width
width

7 6

rd
5
dest
dest
dest
dest
dest
dest
dest

0

opcode
7
AMO
AMO
AMO
AMO
AMO
AMO
AMO

The atomic memory operation (AMO) instructions perform read-modify-write operations for multiprocessor synchronization and are encoded with an R-type instruction format. These AMO instructions atomically load a data value from the address in rs1, place the value into register rd,
apply a binary operator to the loaded value and the original value in rs2, then store the result backto the address in rs1. AMOs can either operate on 64-bit (RV64 only) or 32-bit words in memory.
For RV64, 32-bit AMOs always sign-extend the value placed in rd.

Volume I: RISC-V Unprivileged ISA V20191213

53

For AMOs, the A extension requires that the address held in rs1 be naturally aligned to the sizeof the operand (i.e., eight-byte aligned for 64-bit words and four-byte aligned for 32-bit words). If
the address is not naturally aligned, an address-misaligned exception or an access-fault exception
will be generated. The access-fault exception can be generated for a memory access that would
otherwise be able to complete except for the misalignment, if the misaligned access should not beemulated. The “Zam” extension, described in Chapter 22, relaxes this requirement and specifies
the semantics of misaligned AMOs.
The operations supported are swap, integer add, bitwise AND, bitwise OR, bitwise XOR, andsigned and unsigned integer maximum and minimum. Without ordering constraints, these AMOs
can be used to implement parallel reduction operations, where typically the return value would bediscarded by writing to x0.
We provided fetch-and-op style atomic primitives as they scale to highly parallel systems better
than LR/SC or CAS. A simple microarchitecture can implement AMOs using the LR/SC primitives, provided the implementation can guarantee the AMO eventually completes. More complex
implementations might also implement AMOs at memory controllers, and can optimize away
fetching the original value when the destination is x0.
The set of AMOs was chosen to support the C11/C++11 atomic memory operations efficiently, and also to support parallel reductions in memory. Another use of AMOs is to provide
atomic updates to memory-mapped device registers (e.g., setting, clearing, or toggling bits) in
the I/O space.

To help implement multiprocessor synchronization, the AMOs optionally provide release consistency semantics. If the aq bit is set, then no later memory operations in this RISC-V hart can beobserved to take place before the AMO. Conversely, if the rl bit is set, then other RISC-V harts will
not observe the AMO before memory accesses preceding the AMO in this RISC-V hart. Setting
both the aq and the rl bit on an AMO makes the sequence sequentially consistent, meaning that it
cannot be reordered with earlier or later memory operations from the same hart.
The AMOs were designed to implement the C11 and C++11 memory models efficiently. Although the FENCE R, RW instruction suffices to implement the acquire operation and FENCE
RW, W suffices to implement release, both imply additional unnecessary ordering as comparedto AMOs with the corresponding aq or rl bit set.

An example code sequence for a critical section guarded by a test-and-test-and-set spinlock isshown in Figure 8.2. Note the first AMO is marked aq to order the lock acquisition before thecritical section, and the second AMO is marked rl to order the critical section before the lock
relinquishment.
We recommend the use of the AMO Swap idiom shown above for both lock acquire and releaseto simplify the implementation of speculative lock elision [16].

The instructions in the “A” extension can also be used to provide sequentially consistent loads andstores. A sequentially consistent load can be implemented as an LR with both aq and rl set. A
sequentially consistent store can be implemented as an AMOSWAP that writes the old value to x0
and has both aq and rl set.

54

Volume I: RISC-V Unprivileged ISA V20191213

li
t0, 1
# Initialize swap value.
again:lw
t1, (a0)# Check if lock is held.
bnez
t1, again# Retry if held.
amoswap.w.aq t1, t0, (a0) # Attempt to acquire lock.
bnez
t1, again# Retry if held.
# ...
# Critical section.
# ...
amoswap.w.rl x0, x0, (a0) # Release lock by storing 0.
Figure 8.2: Sample code for mutual exclusion. a0 contains the address of the lock.

Chapter 9“Zicsr”, Control and Status Register(CSR) Instructions, Version 2.0
RISC-V defines a separate address space of 4096 Control and Status registers associated with eachhart. This chapter defines the full set of CSR instructions that operate on these CSRs.
While CSRs are primarily used by the privileged architecture, there are several uses in unprivileged code including for counters and timers, and for floating-point status.
The counters and timers are no longer considered mandatory parts of the standard base
ISAs, and so the CSR instructions required to access them have been moved out of the base ISA
chapter into this separate chapter.

9.1

CSR Instructions

All CSR instructions atomically read-modify-write a single CSR, whose CSR specifier is encodedin the 12-bit csr field of the instruction held in bits 31–20. The immediate forms use a 5-bit
zero-extended immediate encoded in the rs1 field.
31

20 19

csr
12
source/destsource/destsource/destsource/destsource/destsource/dest

15 14

rs1
5
sourcesourcesourceuimm[4:0]
uimm[4:0]
uimm[4:0]

12 11

funct3
3
CSRRW
CSRRS
CSRRC
CSRRWICSRRSICSRRCI

7 6

rd
5
dest
dest
dest
dest
dest
dest

0

opcode7
SYSTEMSYSTEMSYSTEMSYSTEMSYSTEMSYSTEM

The CSRRW (Atomic Read/Write CSR) instruction atomically swaps values in the CSRs andinteger registers. CSRRW reads the old value of the CSR, zero-extends the value to XLEN bits,
then writes it to integer register rd. The initial value in rs1 is written to the CSR. If rd=x0, then55

56

Volume I: RISC-V Unprivileged ISA V20191213

Instruction
CSRRW
CSRRW
CSRRS/CCSRRS/C
Instruction
CSRRWICSRRWICSRRS/CICSRRS/CI

Register operandrd
rs1 read CSR?
x0
no
!x0
yes
x0
yes
!x0
yes
Immediate operandrd uimm read CSR?
x0
no
!x0
yes
0
yes
!0
yes

write CSR?
yes
yes
no
yes
write CSR?
yes
yes
no
yes

Table 9.1: Table showing whether a CSR instruction reads or writes a given CSR. The CSRRS andCSRRC instructions have same behavior so are shown as CSRRS/C in Table.
the instruction shall not read the CSR and shall not cause any of the side effects that might occur
on a CSR read.
The CSRRS (Atomic Read and Set Bits in CSR) instruction reads the value of the CSR, zeroextends the value to XLEN bits, and writes it to integer register rd. The initial value in integer
register rs1 is treated as a bit mask that specifies bit positions to be set in the CSR. Any bit thatis high in rs1 will cause the corresponding bit to be set in the CSR, if that CSR bit is writable.
Other bits in the CSR are unaffected (though CSRs might have side effects when written).
The CSRRC (Atomic Read and Clear Bits in CSR) instruction reads the value of the CSR, zeroextends the value to XLEN bits, and writes it to integer register rd. The initial value in integer
register rs1 is treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bitthat is high in rs1 will cause the corresponding bit to be cleared in the CSR, if that CSR bit iswritable. Other bits in the CSR are unaffected.
For both CSRRS and CSRRC, if rs1=x0, then the instruction will not write to the CSR at all, andso shall not cause any of the side effects that might otherwise occur on a CSR write, such as raising
illegal instruction exceptions on accesses to read-only CSRs. Both CSRRS and CSRRC always readthe addressed CSR and cause any read side effects regardless of rs1 and rd fields. Note that if rs1
specifies a register holding a zero value other than x0, the instruction will still attempt to write
the unmodified value back to the CSR and will cause any attendant side effects. A CSRRW with
rs1=x0 will attempt to write zero to the destination CSR.
The CSRRWI, CSRRSI, and CSRRCI variants are similar to CSRRW, CSRRS, and CSRRC respectively, except they update the CSR using an XLEN-bit value obtained by zero-extending a 5-bit
unsigned immediate (uimm[4:0]) field encoded in the rs1 field instead of a value from an integer
register. For CSRRSI and CSRRCI, if the uimm[4:0] field is zero, then these instructions will notwrite to the CSR, and shall not cause any of the side effects that might otherwise occur on a CSR
write. For CSRRWI, if rd=x0, then the instruction shall not read the CSR and shall not cause anyof the side effects that might occur on a CSR read. Both CSRRSI and CSRRCI will always readthe CSR and cause any read side effects regardless of rd and rs1 fields.

Volume I: RISC-V Unprivileged ISA V20191213

57

Table 9.1 summarizes the behavior of the CSR instructions with respect to whether they read
and/or write the CSR.
The CSRs defined so far do not have any architectural side effects on reads beyond raising illegal
instruction exceptions on disallowed accesses. Custom extensions might add CSRs with side
effects on reads.

Some CSRs, such as the instructions-retired counter, instret, may be modified as side effects of
instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the value
prior to the execution of the instruction. If a CSR access instruction writes such a CSR, the write
is done instead of the increment. In particular, a value written to instret by one instruction willbe the value read by the following instruction.
The assembler pseudoinstruction to read a CSR, CSRR rd, csr, is encoded as CSRRS rd, csr, x0.
The assembler pseudoinstruction to write a CSR, CSRW csr, rs1, is encoded as CSRRW x0, csr,
rs1, while CSRWI csr, uimm, is encoded as CSRRWI x0, csr, uimm.
Further assembler pseudoinstructions are defined to set and clear bits in the CSR when the oldvalue is not required: CSRS/CSRC csr, rs1; CSRSI/CSRCI csr, uimm.

CSR Access Ordering
On a given hart, explicit and implicit CSR access are performed in program order with respect
to those instructions whose execution behavior is affected by the state of the accessed CSR. In
particular, a CSR access is performed after the execution of any prior instructions in program
order whose behavior modifies or is modified by the CSR state and before the execution of any
subsequent instructions in program order whose behavior modifies or is modified by the CSR state.
Furthermore, a CSR read access instruction returns the accessed CSR state before the executionof the instruction, while a CSR write access instruction updates the accessed CSR state after the
execution of the instruction.
Where the above program order does not hold, CSR accesses are weakly ordered, and the local hart
or other harts may observe the CSR accesses in an order different from program order. In addition,
CSR accesses are not ordered with respect to explicit memory accesses, unless a CSR access modifies
the execution behavior of the instruction that performs the explicit memory access or unless a CSR
access and an explicit memory access are ordered by either the syntactic dependencies defined by
the memory model or the ordering requirements defined by the Memory-Ordering PMAs section in
Volume II of this manual. To enforce ordering in all other cases, software should execute a FENCE
instruction between the relevant accesses. For the purposes of the FENCE instruction, CSR readaccesses are classified as device input (I), and CSR write accesses are classified as device output(O).
Informally, the CSR space acts as a weakly ordered memory-mapped I/O region, as defined by
the Memory-Ordering PMAs section in Volume II of this manual. As a result, the order of CSR
accesses with respect to all other accesses is constrained by the same mechanisms that constrain
the order of memory-mapped I/O accesses to such a region.
These CSR-ordering constraints are imposed primarily to support ordering main memory
and memory-mapped I/O accesses with respect to reads of the time CSR. With the exception

58

Volume I: RISC-V Unprivileged ISA V20191213
of the time, cycle, and mcycle CSRs, the CSRs defined thus far in Volumes I and II of thisspecification are not directly accessible to other harts or devices and cause no side effects visible
to other harts or devices. Thus, accesses to CSRs other than the aforementioned three can be
freely reordered with respect to FENCE instructions without violating this specification.

For CSR accesses that cause side effects, the above ordering constraints apply to the order of theinitiation of those side effects but does not necessarily apply to the order of the completion of thoseside effects.
The hardware platform may define that accesses to certain CSRs are strongly ordered, as definedby the Memory-Ordering PMAs section in Volume II of this manual. Accesses to strongly ordered
CSRs have stronger ordering constraints with respect to accesses to both weakly ordered CSRs andaccesses to memory-mapped I/O regions.

Chapter 10

Counters
RISC-V ISAs provide a set of up to 32×64-bit performance counters and timers that are accessible
via unprivileged XLEN read-only CSR registers 0xC00–0xC1F (with the upper 32 bits accessed via
CSR registers 0xC80–0xC9F on RV32). The first three of these (CYCLE, TIME, and INSTRET)
have dedicated functions (cycle count, real-time clock, and instructions-retired respectively), while
the remaining counters, if implemented, provide programmable event counting.

10.1

Base Counters and Timers
31

20 19

csr
12
RDCYCLE[H]
RDTIME[H]RDINSTRET[H]

15 14

rs1
5
0
0
0

12 11

funct3
3
CSRRS
CSRRS
CSRRS

7 6

rd
5
dest
dest
dest

0

opcode7
SYSTEMSYSTEMSYSTEM

RV32I provides a number of 64-bit read-only user-level counters, which are mapped into the 12bit CSR address space and accessed in 32-bit pieces using CSRRS instructions. In RV64I, theCSR instructions can manipulate 64-bit CSRs. In particular, the RDCYCLE, RDTIME, and
RDINSTRET pseudoinstructions read the full 64 bits of the cycle, time, and instret counters.
Hence, the RDCYCLEH, RDTIMEH, and RDINSTRETH instructions are not required in RV64I.
Some execution environments might prohibit access to counters to impede timing side-channel
attacks.

The RDCYCLE pseudoinstruction reads the low XLEN bits of the cycle CSR which holds a countof the number of clock cycles executed by the processor core on which the hart is running from anarbitrary start time in the past. RDCYCLEH is an RV32I instruction that reads bits 63–32 of thesame cycle counter. The underlying 64-bit counter should never overflow in practice. The rate at
which the cycle counter advances will depend on the implementation and operating environment.
The execution environment should provide a means to determine the current rate (cycles/second)
at which the cycle counter is incrementing.
59

60

Volume I: RISC-V Unprivileged ISA V20191213

RDCYCLE is intended to return the number of cycles executed by the processor core, not thehart. Precisely defining what is a “core” is difficult given some implementation choices (e.g.,
AMD Bulldozer). Precisely defining what is a “clock cycle” is also difficult given the range of
implementations (including software emulations), but the intent is that RDCYCLE is used for
performance monitoring along with the other performance counters. In particular, where there
is one hart/core, one would expect cycle-count/instructions-retired to measure CPI for a hart.
Cores don’t have to be exposed to software at all, and an implementor might choose topretend multiple harts on one physical core are running on separate cores with one hart/core,and provide separate cycle counters for each hart. This might make sense in a simple barrel
processor (e.g., CDC 6600 peripheral processors) where inter-hart timing interactions are nonexistent or minimal.
Where there is more than one hart/core and dynamic multithreading, it is not generally
possible to separate out cycles per hart (especially with SMT). It might be possible to define
a separate performance counter that tried to capture the number of cycles a particular hart
was running, but this definition would have to be very fuzzy to cover all the possible threading
implementations. For example, should we only count cycles for which any instruction was issued
to execution for this hart, and/or cycles any instruction retired, or include cycles this hart
was occupying machine resources but couldn’t execute due to stalls while other harts went into
execution? Likely, “all of the above” would be needed to have understandable performance stats.
This complexity of defining a per-hart cycle count, and also the need in any case for a total
per-core cycle count when tuning multithreaded code led to just standardizing the per-core cycle
counter, which also happens to work well for the common single hart/core case.
Standardizing what happens during “sleep” is not practical given that what “sleep” means is
not standardized across execution environments, but if the entire core is paused (entirely clockgated or powered-down in deep sleep), then it is not executing clock cycles, and the cycle countshouldn’t be increasing per the spec. There are many details, e.g., whether clock cycles required
to reset a processor after waking up from a power-down event should be counted, and these areconsidered execution-environment-specific details.
Even though there is no precise definition that works for all platforms, this is still a usefulfacility for most platforms, and an imprecise, common, “usually correct” standard here is better
than no standard. The intent of RDCYCLE was primarily performance monitoring/tuning, andthe specification was written with that goal in mind.

The RDTIME pseudoinstruction reads the low XLEN bits of the time CSR, which counts wall-clock
real time that has passed from an arbitrary start time in the past. RDTIMEH is an RV32I-only instruction that reads bits 63–32 of the same real-time counter. The underlying 64-bit counter should
never overflow in practice. The execution environment should provide a means of determining theperiod of the real-time counter (seconds/tick). The period must be constant. The real-time clocksof all harts in a single user application should be synchronized to within one tick of the real-timeclock. The environment should provide a means to determine the accuracy of the clock.
On some simple platforms, cycle count might represent a valid implementation of RDTIME, but
in this case, platforms should implement the RDTIME instruction as an alias for RDCYCLE
to make code more portable, rather than using RDCYCLE to measure wall-clock time.

The RDINSTRET pseudoinstruction reads the low XLEN bits of the instret CSR, which counts
the number of instructions retired by this hart from some arbitrary start point in the past.
RDINSTRETH is an RV32I-only instruction that reads bits 63–32 of the same instruction counter.
The underlying 64-bit counter should never overflow in practice.

Volume I: RISC-V Unprivileged ISA V20191213

61

The following code sequence will read a valid 64-bit cycle counter value into x3:x2, even if thecounter overflows its lower half between reading its upper and lower halves.
again:
rdcyclehrdcyclerdcycleh
bne

x3
x2
x4
x3, x4, again

Figure 10.1: Sample code for reading the 64-bit cycle counter in RV32.
We recommend provision of these basic counters in implementations as they are essential forbasic performance analysis, adaptive and dynamic optimization, and to allow an application towork with real-time streams. Additional counters should be provided to help diagnose performance
problems and these should be made accessible from user-level application code with low overhead.
We required the counters be 64 bits wide, even on RV32, as otherwise it is very difficult forsoftware to determine if values have overflowed. For a low-end implementation, the upper 32
bits of each counter can be implemented using software counters incremented by a trap handler
triggered by overflow of the lower 32 bits. The sample code described above shows how the full
64-bit width value can be safely read using the individual 32-bit instructions.
In some applications, it is important to be able to read multiple counters at the same instantin time. When run under a multitasking environment, a user thread can suffer a context switch
while attempting to read the counters. One solution is for the user thread to read the real-time
counter before and after reading the other counters to determine if a context switch occurred in
the middle of the sequence, in which case the reads can be retried. We considered adding output
latches to allow a user thread to snapshot the counter values atomically, but this would increase
the size of the user context, especially for implementations with a richer set of counters.

10.2

Hardware Performance Counters

There is CSR space allocated for 29 additional unprivileged 64-bit hardware performance counters, hpmcounter3–hpmcounter31. For RV32, the upper 32 bits of these performance counters
is accessible via additional CSRs hpmcounter3h–hpmcounter31h. These counters count platformspecific events and are configured via additional privileged registers. The number and width ofthese additional counters, and the set of events they count is platform-specific.
The privileged architecture manual describes the privileged CSRs controlling access to these counters and to set the events to be counted.
It would be useful to eventually standardize event settings to count ISA-level metrics, suchas the number of floating-point instructions executed for example, and possibly a few common
microarchitectural metrics, such as “L1 instruction cache misses”.

62

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 11“F” Standard Extension forSingle-Precision Floating-Point,
Version 2.2
This chapter describes the standard instruction-set extension for single-precision floating-point,
which is named “F” and adds single-precision floating-point computational instructions compliant
with the IEEE 754-2008 arithmetic standard [7]. The F extension depends on the “Zicsr” extension
for control and status register access.

11.1

F Register StateThe F extension adds 32 floating-point registers, f0–f31, each 32 bits wide, and a floating-point
control and status register fcsr, which contains the operating mode and exception status of thefloating-point unit. This additional state is shown in Figure 11.1. We use the term FLEN to
describe the width of the floating-point registers in the RISC-V ISA, and FLEN=32 for the F
single-precision floating-point extension. Most floating-point instructions operate on values in the
floating-point register file. Floating-point load and store instructions transfer floating-point values
between registers and memory. Instructions to transfer values to and from the integer register file
are also provided.
We considered a unified register file for both integer and floating-point values as this simplifies
software register allocation and calling conventions, and reduces total user state. However,a split organization increases the total number of registers accessible with a given instruction
width, simplifies provision of enough regfile ports for wide superscalar issue, supports decoupled
floating-point-unit architectures, and simplifies use of internal floating-point encoding techniques.
Compiler support and calling conventions for split register file architectures are well understood,
and using dirty bits on floating-point register file state can reduce context-switch overhead.

63

64

Volume I: RISC-V Unprivileged ISA V20191213

FLEN-1

0

f0
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
f11
f12
f13
f14
f15
f16
f17
f18
f19
f20
f21
f22
f23
f24
f25
f26
f27
f28
f29
f30
f31
FLEN
31

0

fcsr
32

Figure 11.1: RISC-V standard F extension single-precision floating-point state.

Volume I: RISC-V Unprivileged ISA V20191213

11.2

65

Floating-Point Control and Status Register

The floating-point control and status register, fcsr, is a RISC-V control and status register (CSR).
It is a 32-bit read/write register that selects the dynamic rounding mode for floating-point arithmetic operations and holds the accrued exception flags, as shown in Figure 11.2.
31

87

5

Reserved

Rounding Mode (frm)

24

3

4

3

2

1

0

Accrued Exceptions (fflags)
NV DZ OF UF
NX
1
1
1
1
1

Figure 11.2: Floating-point control and status register.
The fcsr register can be read and written with the FRCSR and FSCSR instructions, which areassembler pseudoinstructions built on the underlying CSR access instructions. FRCSR reads fcsr
by copying it into integer register rd. FSCSR swaps the value in fcsr by copying the original value
into integer register rd, and then writing a new value obtained from integer register rs1 into fcsr.
The fields within the fcsr can also be accessed individually through different CSR addresses, andseparate assembler pseudoinstructions are defined for these accesses. The FRRM instruction reads
the Rounding Mode field frm and copies it into the least-significant three bits of integer registerrd, with zero in all other bits. FSRM swaps the value in frm by copying the original value into
integer register rd, and then writing a new value obtained from the three least-significant bits ofinteger register rs1 into frm. FRFLAGS and FSFLAGS are defined analogously for the Accrued
Exception Flags field fflags.
Bits 31–8 of the fcsr are reserved for other standard extensions, including the “L” standard
extension for decimal floating-point. If these extensions are not present, implementations shall
ignore writes to these bits and supply a zero value when read. Standard software should preserve
the contents of these bits.
Floating-point operations use either a static rounding mode encoded in the instruction, or a dynamic
rounding mode held in frm. Rounding modes are encoded as shown in Table 11.1. A value of 111 in
the instruction’s rm field selects the dynamic rounding mode held in frm. If frm is set to an invalid
value (101–111), any subsequent attempt to execute a floating-point operation with a dynamic
rounding mode will raise an illegal instruction exception. Some instructions, including widening
conversions, have the rm field but are nevertheless unaffected by the rounding mode; software
should set their rm field to RNE (000).
The C99 language standard effectively mandates the provision of a dynamic rounding mode register. In typical implementations, writes to the dynamic rounding mode CSR state will serialize
the pipeline.
Static rounding modes are used to implement specialized arithmetic operations that often
have to switch frequently between different rounding modes.

66

Volume I: RISC-V Unprivileged ISA V20191213
Rounding Mode
000
001
010
011
100
101
110
111

Mnemonic
RNE
RTZ
RDN
RUP
RMM

DYN

MeaningRound to Nearest, ties to Even
Round towards ZeroRound Down (towards −∞)Round Up (towards +∞)Round to Nearest, ties to Max Magnitude
Invalid. Reserved for future use.
Invalid. Reserved for future use.
In instruction’s rm field, selects dynamic rounding mode;
In Rounding Mode register, Invalid.

Table 11.1: Rounding mode encoding.
The accrued exception flags indicate the exception conditions that have arisen on any floating-point
arithmetic instruction since the field was last reset by software, as shown in Table 11.2. The baseRISC-V ISA does not support generating a trap on the setting of a floating-point exception flag.
Flag Mnemonic
NV
DZ
OF
UF
NX

Flag Meaning
Invalid Operation
Divide by Zero
Overflow
Underflow
Inexact

Table 11.2: Accrued exception flag encoding.
As allowed by the standard, we do not support traps on floating-point exceptions in the base
ISA, but instead require explicit checks of the flags in software. We considered adding branches
controlled directly by the contents of the floating-point accrued exception flags, but ultimately
chose to omit these instructions to keep the ISA simple.

11.3

NaN Generation and Propagation

Except when otherwise stated, if the result of a floating-point operation is NaN, it is the canonical
NaN. The canonical NaN has a positive sign and all significand bits clear except the MSB, a.k.a.
the quiet bit. For single-precision floating-point, this corresponds to the pattern 0x7fc00000.
We considered propagating NaN payloads, as is recommended by the standard, but this decision
would have increased hardware cost. Moreover, since this feature is optional in the standard, itcannot be used in portable code.
Implementors are free to provide a NaN payload propagation scheme as a nonstandard extension enabled by a nonstandard operating mode. However, the canonical NaN scheme describedabove must always be supported and should be the default mode.
We require implementations to return the standard-mandated default values in the case of exceptional conditions, without any further intervention on the part of user-level software (unlike
the Alpha ISA floating-point trap barriers). We believe full hardware handling of exceptional

Volume I: RISC-V Unprivileged ISA V20191213

67

cases will become more common, and so wish to avoid complicating the user-level ISA to optimize other approaches. Implementations can always trap to machine-mode software handlers toprovide exceptional default values.

11.4

Subnormal Arithmetic

Operations on subnormal numbers are handled in accordance with the IEEE 754-2008 standard.
In the parlance of the IEEE standard, tininess is detected after rounding.
Detecting tininess after rounding results in fewer spurious underflow signals.

11.5

Single-Precision Load and Store Instructions

Floating-point loads and stores use the same base+offset addressing mode as the integer base ISA,
with a base address in register rs1 and a 12-bit signed byte offset. The FLW instruction loads
a single-precision floating-point value from memory into floating-point register rd. FSW stores asingle-precision value from floating-point register rs2 to memory.
31

20 19

imm[11:0]
12
offset[11:0]

31

rs1
5
base

25 24

imm[11:5]
7
offset[11:5]

15 14

20 19

rs2
5
src

width
3
W

15 14

rs1
5
base

12 11

7 6

rd
5
dest

12 11

width
3
W

imm[4:0]
5
offset[4:0]0opcode7
LOAD-FP

7 60

opcode7
STORE-FP

FLW and FSW are only guaranteed to execute atomically if the effective address is naturallyaligned.
FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical
NaNs are preserved.

11.6

Single-Precision Floating-Point Computational Instructions

Floating-point arithmetic instructions with one or two source operands use the R-type format with
the OP-FP major opcode. FADD.S and FMUL.S perform single-precision floating-point addition

68

Volume I: RISC-V Unprivileged ISA V20191213

and multiplication respectively, between rs1 and rs2. FSUB.S performs the single-precision floatingpoint subtraction of rs2 from rs1. FDIV.S performs the single-precision floating-point division of
rs1 by rs2. FSQRT.S computes the square root of rs1. In each case, the result is written to rd.
The 2-bit floating-point format field fmt is encoded as shown in Table 11.3. It is set to S (00) for
all instructions in the F extension.
fmt field
00
01
10
11

MnemonicS
D
H
Q

Meaning
32-bit single-precision64-bit double-precision
16-bit half-precision128-bit quad-precision

Table 11.3: Format field encoding.
All floating-point operations that perform rounding can select the rounding mode using the rm
field with the encoding shown in Table 11.1.
Floating-point minimum-number and maximum-number instructions FMIN.S and FMAX.S write,
respectively, the smaller or larger of rs1 and rs2 to rd. For the purposes of these instructions only,
the value −0.0 is considered to be less than the value +0.0. If both inputs are NaNs, the result isthe canonical NaN. If only one operand is a NaN, the result is the non-NaN operand. Signaling
NaN inputs set the invalid operation exception flag, even when the result is not NaN.
Note that in version 2.2 of the F extension, the FMIN.S and FMAX.S instructions were amended
to implement the proposed IEEE 754-201x minimumNumber and maximumNumber operations,rather than the IEEE 754-2008 minNum and maxNum operations. These operations differ intheir handling of signaling NaNs.
31

27 26

funct5fmt
5
2
FADD/FSUB S
FMUL/FDIV S
FSQRTSFMIN-MAX
S

25 24

20 19

rs2
5
src2
src2
0
src2

15 14

rs1
5
src1
src1
src
src1

12 11

rm
rd
3
5
RM
dest
RM
dest
RM
dest
MIN/MAX dest

7 60

opcode
7
OP-FP
OP-FP
OP-FP
OP-FP

Floating-point fused multiply-add instructions require a new standard instruction format. R4-type
instructions specify three source registers (rs1, rs2, and rs3) and a destination register (rd). This
format is only used by the floating-point fused multiply-add instructions.
FMADD.S multiplies the values in rs1 and rs2, adds the value in rs3, and writes the final result tord. FMADD.S computes (rs1×rs2)+rs3.
FMSUB.S multiplies the values in rs1 and rs2, subtracts the value in rs3, and writes the final result
to rd. FMSUB.S computes (rs1×rs2)-rs3.
FNMSUB.S multiplies the values in rs1 and rs2, negates the product, adds the value in rs3, andwrites the final result to rd. FNMSUB.S computes -(rs1×rs2)+rs3.

Volume I: RISC-V Unprivileged ISA V20191213

69

FNMADD.S multiplies the values in rs1 and rs2, negates the product, subtracts the value in rs3,
and writes the final result to rd. FNMADD.S computes -(rs1×rs2)-rs3.
The FNMSUB and FNMADD instructions are counterintuitively named, owing to the namingof the corresponding instructions in MIPS-IV. The MIPS instructions were defined to negate
the sum, rather than negating the product as the RISC-V instructions do, so the naming scheme
was more rational at the time. The two definitions differ with respect to signed-zero results. The
RISC-V definition matches the behavior of the x86 and ARM fused multiply-add instructions, but
unfortunately the RISC-V FNMSUB and FNMADD instruction names are swapped comparedto x86 and ARM.
31

27 26

rs3
5
src3

fmt
2
S

25 24

20 19

rs2
5
src2

15 14

rs1
5
src1

rm
3
RM

12 11

7 6

rd
5
dest

0

opcode7
F[N]MADD/F[N]MSUB

The fused multiply-add (FMA) instructions consume a large part of the 32-bit instruction encoding space. Some alternatives considered were to restrict FMA to only use dynamic rounding
modes, but static rounding modes are useful in code that exploits the lack of product rounding.
Another alternative would have been to use rd to provide rs3, but this would require additional
move instructions in some common sequences. The current design still leaves a large portion of
the 32-bit encoding space open while avoiding having FMA be non-orthogonal.

The fused multiply-add instructions must set the invalid operation exception flag when the multiplicands are ∞ and zero, even when the addend is a quiet NaN.
The IEEE 754-2008 standard permits, but does not require, raising the invalid exception for theoperation ∞ × 0 + qNaN.

11.7

Single-Precision
Instructions

Floating-Point

Conversion

and

Move

Floating-point-to-integer and integer-to-floating-point conversion instructions are encoded in the
OP-FP major opcode space. FCVT.W.S or FCVT.L.S converts a floating-point number in floatingpoint register rs1 to a signed 32-bit or 64-bit integer, respectively, in integer register rd. FCVT.S.W
or FCVT.S.L converts a 32-bit or 64-bit signed integer, respectively, in integer register rs1 into afloating-point number in floating-point register rd. FCVT.WU.S, FCVT.LU.S, FCVT.S.WU, and
FCVT.S.LU variants convert to or from unsigned integer values. For XLEN> 32, FCVT.W[U].S
sign-extends the 32-bit result to the destination register width. FCVT.L[U].S and FCVT.S.L[U]
are RV64-only instructions. If the rounded result is not representable in the destination format, it
is clipped to the nearest value and the invalid flag is set. Table 11.4 gives the range of valid inputs
for FCVT.int.S and the behavior for invalid inputs.
All floating-point to integer and integer to floating-point conversion instructions round according
to the rm field. A floating-point register can be initialized to floating-point positive zero using
FCVT.S.W rd, x0, which will never set any exception flags.

70

Volume I: RISC-V Unprivileged ISA V20191213

Minimum valid input (after rounding)Maximum valid input (after rounding)
Output for out-of-range negative input
Output for −∞Output for out-of-range positive input
Output for +∞ or NaN

FCVT.W.S
−231
31
2 −1
−231
−231
31
2 −1
231 − 1

FCVT.WU.S
0232 − 100232 − 1232 − 1

FCVT.L.S
−263
63
2 −1
−263
−263
63
2 −1
263 − 1

FCVT.LU.S
0264 − 100264 − 1264 − 1

Table 11.4: Domains of float-to-integer conversions and behavior for invalid inputs.

31

27 26

funct5fmt
5
2
FCVT.int.fmt S
FCVT.fmt.int S

25 24

20 19

rs2
5
W[U]/L[U]
W[U]/L[U]

15 14

rs1
5
src
src

12 11

rm
3
RM
RM

7 6

rd
5
dest
dest

0

opcode
7
OP-FP
OP-FP

Floating-point to floating-point sign-injection instructions, FSGNJ.S, FSGNJN.S, and FSGNJX.S,
produce a result that takes all bits except the sign bit from rs1. For FSGNJ, the result’s sign bit is
rs2’s sign bit; for FSGNJN, the result’s sign bit is the opposite of rs2’s sign bit; and for FSGNJX,
the sign bit is the XOR of the sign bits of rs1 and rs2. Sign-injection instructions do not set
floating-point exception flags, nor do they canonicalize NaNs. Note, FSGNJ.S rx, ry, ry moves ry
to rx (assembler pseudoinstruction FMV.S rx, ry); FSGNJN.S rx, ry, ry moves the negation of ry
to rx (assembler pseudoinstruction FNEG.S rx, ry); and FSGNJX.S rx, ry, ry moves the absolutevalue of ry to rx (assembler pseudoinstruction FABS.S rx, ry).
31

27 26

funct5
5
FSGNJ

fmt
2
S

25 24

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

rm
3
J[N]/JX

7 6

rd
5
dest

0

opcode7
OP-FP

The sign-injection instructions provide floating-point MV, ABS, and NEG, as well as supportinga few other operations, including the IEEE copySign operation and sign manipulation in transcendental math function libraries. Although MV, ABS, and NEG only need a single register
operand, whereas FSGNJ instructions need two, it is unlikely most microarchitectures would add
optimizations to benefit from the reduced number of register reads for these relatively infrequent
instructions. Even in this case, a microarchitecture can simply detect when both source registers
are the same for FSGNJ instructions and only read a single copy.

Instructions are provided to move bit patterns between the floating-point and integer registers.
FMV.X.W moves the single-precision value in floating-point register rs1 represented in IEEE 7542008 encoding to the lower 32 bits of integer register rd. The bits are not modified in the transfer,and in particular, the payloads of non-canonical NaNs are preserved. For RV64, the higher 32 bitsof the destination register are filled with copies of the floating-point number’s sign bit.
FMV.W.X moves the single-precision value encoded in IEEE 754-2008 standard encoding from thelower 32 bits of integer register rs1 to the floating-point register rd. The bits are not modified in
the transfer, and in particular, the payloads of non-canonical NaNs are preserved.

Volume I: RISC-V Unprivileged ISA V20191213

71

The FMV.W.X and FMV.X.W instructions were previously called FMV.S.X and FMV.X.S. The
use of W is more consistent with their semantics as an instruction that moves 32 bits without
interpreting them. This became clearer after defining NaN-boxing. To avoid disturbing existing
code, both the W and S versions will be supported by tools.

31

27 26

funct5
5
FMV.X.W
FMV.W.X

25 24

fmt
2
S
S

20 19

rs2
5
0
0

15 14

rs1
5
src
src

12 11

rm
3
000
000

7 6

rd
5
dest
dest

0

opcode
7
OP-FP
OP-FP

The base floating-point ISA was defined so as to allow implementations to employ an internal
recoding of the floating-point format in registers to simplify handling of subnormal values andpossibly to reduce functional unit latency. To this end, the base ISA avoids representing integer
values in the floating-point registers by defining conversion and comparison operations that read
and write the integer register file directly. This also removes many of the common cases where
explicit moves between integer and floating-point registers are required, reducing instruction countand critical paths for common mixed-format code sequences.

11.8

Single-Precision Floating-Point Compare Instructions

Floating-point compare instructions (FEQ.S, FLT.S, FLE.S) perform the specified comparison between floating-point registers (rs1 = rs2, rs1 < rs2, rs1 ≤ rs2) writing 1 to the integer register rd
if the condition holds, and 0 otherwise.
FLT.S and FLE.S perform what the IEEE 754-2008 standard refers to as signaling comparisons:that is, they set the invalid operation exception flag if either input is NaN. FEQ.S performs a quiet
comparison: it only sets the invalid operation exception flag if either input is a signaling NaN. For
all three instructions, the result is 0 if either operand is NaN.
31

27 26

funct5
5
FCMP

fmt
2
S

25 24

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

rm
rd
3
5
EQ/LT/LE dest

7 60

opcode7
OP-FP

The F extension provides a ≤ comparison, whereas the base ISA provides a ≥ branch comparison.
Because ≤ can be synthesized from ≥ and vice-versa, there is no performance implication to thisinconsistency, but it is nevertheless an unfortunate incongruity in the ISA.

11.9

Single-Precision Floating-Point Classify Instruction

The FCLASS.S instruction examines the value in floating-point register rs1 and writes to integer
register rd a 10-bit mask that indicates the class of the floating-point number. The format of the72

Volume I: RISC-V Unprivileged ISA V20191213

mask is described in Table 11.5. The corresponding bit in rd will be set if the property is trueand clear otherwise. All other bits in rd are cleared. Note that exactly one bit in rd will be set.
FCLASS.S does not set the floating-point exception flags.
31

27 26

funct5
5
FCLASS

25 24

fmt
2
S

20 19

rs2
5
0

rd bit
0
1
2
3
4
5
6
7
8
9

15 14

rs1
5
src

rm
3
001

12 11

7 6

rd
5
dest

Meaning
rs1 is −∞.
rs1 is a negative normal number.
rs1 is a negative subnormal number.
rs1 is −0.
rs1 is +0.
rs1 is a positive subnormal number.
rs1 is a positive normal number.
rs1 is +∞.
rs1 is a signaling NaN.
rs1 is a quiet NaN.

Table 11.5: Format of result of FCLASS instruction.

0

opcode7
OP-FP

Chapter 12“D” Standard Extension for
Double-Precision Floating-Point,
Version 2.2
This chapter describes the standard double-precision floating-point instruction-set extension, whichis named “D” and adds double-precision floating-point computational instructions compliant with
the IEEE 754-2008 arithmetic standard. The D extension depends on the base single-precision
instruction subset F.

12.1

D Register StateThe D extension widens the 32 floating-point registers, f0–f31, to 64 bits (FLEN=64 in Figure 11.1). The f registers can now hold either 32-bit or 64-bit floating-point values as described
below in Section 12.2.
FLEN can be 32, 64, or 128 depending on which of the F, D, and Q extensions are supported.
There can be up to four different floating-point precisions supported, including H, F, D, and Q.

12.2

NaN Boxing of Narrower Values

When multiple floating-point precisions are supported, then valid values of narrower n-bit types,
n < FLEN, are represented in the lower n bits of an FLEN-bit NaN value, in a process termed
NaN-boxing. The upper bits of a valid NaN-boxed value must be all 1s. Valid NaN-boxed n-bit
values therefore appear as negative quiet NaNs (qNaNs) when viewed as any wider m-bit value,n < m ≤ FLEN. Any operation that writes a narrower result to an f register must write all 1s tothe uppermost FLEN−n bits to yield a legal NaN-boxed value.

73

74

Volume I: RISC-V Unprivileged ISA V20191213

Software might not know the current type of data stored in a floating-point register but has to beable to save and restore the register values, hence the result of using wider operations to transfer
narrower values has to be defined. A common case is for callee-saved registers, but a standard
convention is also desirable for features including varargs, user-level threading libraries, virtual
machine migration, and debugging.

Floating-point n-bit transfer operations move external values held in IEEE standard formats intoand out of the f registers, and comprise floating-point loads and stores (FLn/FSn) and floatingpoint move instructions (FMV.n.X/FMV.X.n). A narrower n-bit transfer, n < FLEN, into the fregisters will create a valid NaN-boxed value. A narrower n-bit transfer out of the floating-point
registers will transfer the lower n bits of the register ignoring the upper FLEN−n bits.
Apart from transfer operations described in the previous paragraph, all other floating-point operations on narrower n-bit operations, n < FLEN, check if the input operands are correctly NaN-boxed,i.e., all upper FLEN−n bits are 1. If so, the n least-significant bits of the input are used as the
input value, otherwise the input value is treated as an n-bit canonical NaN.
Earlier versions of this document did not define the behavior of feeding the results of narrower or
wider operands into an operation, except to require that wider saves and restores would preserve
the value of a narrower operand. The new definition removes this implementation-specific behavior, while still accommodating both non-recoded and recoded implementations of the floating-point
unit. The new definition also helps catch software errors by propagating NaNs if values are used
incorrectly.
Non-recoded implementations unpack and pack the operands to IEEE standard format on
the input and output of every floating-point operation. The NaN-boxing cost to a non-recoded
implementation is primarily in checking if the upper bits of a narrower operation represent alegal NaN-boxed value, and in writing all 1s to the upper bits of a result.
Recoded implementations use a more convenient internal format to represent floating-pointvalues, with an added exponent bit to allow all values to be held normalized. The cost to therecoded implementation is primarily the extra tagging needed to track the internal types andsign bits, but this can be done without adding new state bits by recoding NaNs internally in the
exponent field. Small modifications are needed to the pipelines used to transfer values in andout of the recoded format, but the datapath and latency costs are minimal. The recoding process
has to handle shifting of input subnormal values for wide operands in any case, and extracting
the NaN-boxed value is a similar process to normalization except for skipping over leading-1 bits
instead of skipping over leading-0 bits, allowing the datapath muxing to be shared.

12.3

Double-Precision Load and Store Instructions

The FLD instruction loads a double-precision floating-point value from memory into floating-point
register rd. FSD stores a double-precision value from the floating-point registers to memory.
The double-precision value may be a NaN-boxed single-precision value.
31

20 19

imm[11:0]
12
offset[11:0]

15 14

rs1
5
base

12 11

width
3
D

7 6

rd
5
dest

0

opcode7
LOAD-FP

Volume I: RISC-V Unprivileged ISA V20191213

31

25 24

imm[11:5]
7
offset[11:5]

20 19

rs2
5
src

75

15 14

rs1
5
base

12 11

width
3
D

7 6

imm[4:0]
5
offset[4:0]0opcode7
STORE-FP

FLD and FSD are only guaranteed to execute atomically if the effective address is naturally aligned
and XLEN≥64.
FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical
NaNs are preserved.

12.4

Double-Precision Floating-Point Computational Instructions

The double-precision floating-point computational instructions are defined analogously to theirsingle-precision counterparts, but operate on double-precision operands and produce doubleprecision results.
31

27 26

25 24

funct5fmt
5
2
FADD/FSUB D
FMUL/FDIV D
FMIN-MAX
D
FSQRT
D

31

27 26

rs3
5
src3

12.5

fmt
2
D

20 19

rs2
5
src2
src2
src2
0

25 24

15 14

rs1
5
src1
src1
src1
src

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

7 6

rm
rd
3
5
RM
dest
RM
dest
MIN/MAX dest
RM
dest

rm
3
RM

12 11

7 6

rd
5
dest

0

opcode
7
OP-FP
OP-FP
OP-FP
OP-FP

0

opcode7
F[N]MADD/F[N]MSUB

Double-Precision Floating-Point Conversion and Move Instructions

Floating-point-to-integer and integer-to-floating-point conversion instructions are encoded in the
OP-FP major opcode space. FCVT.W.D or FCVT.L.D converts a double-precision floating-point
number in floating-point register rs1 to a signed 32-bit or 64-bit integer, respectively, in integer register rd. FCVT.D.W or FCVT.D.L converts a 32-bit or 64-bit signed integer, respectively, in integer register rs1 into a double-precision floating-point number in floating-point register rd. FCVT.WU.D, FCVT.LU.D, FCVT.D.WU, and FCVT.D.LU variants convert to or fromunsigned integer values. For RV64, FCVT.W[U].D sign-extends the 32-bit result. FCVT.L[U].D
and FCVT.D.L[U] are RV64-only instructions. The range of valid inputs for FCVT.int.D and the
behavior for invalid inputs are the same as for FCVT.int.S.

76

Volume I: RISC-V Unprivileged ISA V20191213

All floating-point to integer and integer to floating-point conversion instructions round according
to the rm field. Note FCVT.D.W[U] always produces an exact result and is unaffected by rounding
mode.
31

27 26

funct5
5
FCVT.int.D
FCVT.D.int

fmt
2
D
D

25 24

20 19

rs2
5
W[U]/L[U]
W[U]/L[U]

15 14

rs1
5
src
src

12 11

rm
3
RM
RM

7 6

rd
5
dest
dest

0

opcode
7
OP-FP
OP-FP

The double-precision to single-precision and single-precision to double-precision conversion instructions, FCVT.S.D and FCVT.D.S, are encoded in the OP-FP major opcode space and both thesource and destination are floating-point registers. The rs2 field encodes the datatype of thesource, and the fmt field encodes the datatype of the destination. FCVT.S.D rounds according to
the RM field; FCVT.D.S will never round.
31

27 26

funct5
5
FCVT.S.D
FCVT.D.S

25 24

fmt
2
S
D

20 19

rs2
5
D
S

15 14

rs1
5
src
src

12 11

rm
3
RM
RM

7 6

rd
5
dest
dest

0

opcode
7
OP-FP
OP-FP

Floating-point to floating-point sign-injection instructions, FSGNJ.D, FSGNJN.D, and FSGNJX.D
are defined analogously to the single-precision sign-injection instruction.
31

27 26

funct5
5
FSGNJ

25 24

fmt
2
D

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

rm
3
J[N]/JX

7 6

rd
5
dest

0

opcode7
OP-FP

For XLEN≥64 only, instructions are provided to move bit patterns between the floating-point andinteger registers. FMV.X.D moves the double-precision value in floating-point register rs1 to arepresentation in IEEE 754-2008 standard encoding in integer register rd. FMV.D.X moves the
double-precision value encoded in IEEE 754-2008 standard encoding from the integer register rs1
to the floating-point register rd.
FMV.X.D and FMV.D.X do not modify the bits being transferred; in particular, the payloads of
non-canonical NaNs are preserved.
31

27 26

funct5
5
FMV.X.D
FMV.D.X

fmt
2
D
D

25 24

20 19

rs2
5
0
0

15 14

rs1
5
src
src

rm
3
000
000

12 11

7 6

rd
5
dest
dest

0

opcode
7
OP-FP
OP-FP

Volume I: RISC-V Unprivileged ISA V20191213

77

Early versions of the RISC-V ISA had additional instructions to allow RV32 systems to transfer
between the upper and lower portions of a 64-bit floating-point register and an integer register.
However, these would be the only instructions with partial register writes and would add complexity in implementations with recoded floating-point or register renaming, requiring a pipeline
read-modify-write sequence. Scaling up to handling quad-precision for RV32 and RV64 would
also require additional instructions if they were to follow this pattern. The ISA was defined toreduce the number of explicit int-float register moves, by having conversions and comparisonswrite results to the appropriate register file, so we expect the benefit of these instructions to belower than for other ISAs.
We note that for systems that implement a 64-bit floating-point unit including fused multiplyadd support and 64-bit floating-point loads and stores, the marginal hardware cost of moving froma 32-bit to a 64-bit integer datapath is low, and a software ABI supporting 32-bit wide addressspace and pointers can be used to avoid growth of static data and dynamic memory traffic.

12.6

Double-Precision Floating-Point Compare Instructions

The double-precision floating-point compare instructions are defined analogously to their singleprecision counterparts, but operate on double-precision operands.
31

27 26

funct5
5
FCMP

12.7

25 24

fmt
2
D

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

7 6

rm
rd
3
5
EQ/LT/LE dest

0

opcode7
OP-FP

Double-Precision Floating-Point Classify Instruction

The double-precision floating-point classify instruction, FCLASS.D, is defined analogously to its
single-precision counterpart, but operates on double-precision operands.
31

27 26

funct5
5
FCLASS

fmt
2
D

25 24

20 19

rs2
5
0

15 14

rs1
5
src

rm
3
001

12 11

7 6

rd
5
dest

0

opcode
7
OP-FP

78

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 13“Q” Standard Extension for
Quad-Precision Floating-Point,
Version 2.2
This chapter describes the Q standard extension for 128-bit quad-precision binary floating-point
instructions compliant with the IEEE 754-2008 arithmetic standard. The quad-precision binary
floating-point instruction-set extension is named “Q”; it depends on the double-precision floatingpoint extension D. The floating-point registers are now extended to hold either a single, double, orquad-precision floating-point value (FLEN=128). The NaN-boxing scheme described in Section 12.2
is now extended recursively to allow a single-precision value to be NaN-boxed inside a doubleprecision value which is itself NaN-boxed inside a quad-precision value.

13.1

Quad-Precision Load and Store Instructions

New 128-bit variants of LOAD-FP and STORE-FP instructions are added, encoded with a newvalue for the funct3 width field.
31

20 19

imm[11:0]
12
offset[11:0]

31

rs1
5
base

25 24

imm[11:5]
7
offset[11:5]

15 14

20 19

rs2
5
src

12 11

width
3
Q

15 14

rs1
5
base

7 6

rd
5
dest

12 11

width
3
Q

imm[4:0]
5
offset[4:0]0opcode7
LOAD-FP

7 60

opcode7
STORE-FP

FLQ and FSQ are only guaranteed to execute atomically if the effective address is naturally aligned
and XLEN=128.
79

80

Volume I: RISC-V Unprivileged ISA V20191213

FLQ and FSQ do not modify the bits being transferred; in particular, the payloads of non-canonical
NaNs are preserved.

13.2

Quad-Precision Computational Instructions

A new supported format is added to the format field of most instructions, as shown in Table 13.1.
fmt field
00
01
10
11

MnemonicS
D
H
Q

Meaning
32-bit single-precision64-bit double-precision
16-bit half-precision128-bit quad-precision

Table 13.1: Format field encoding.
The quad-precision floating-point computational instructions are defined analogously to their
double-precision counterparts, but operate on quad-precision operands and produce quad-precision
results.
31

27 26

25 24

funct5fmt
5
2
FADD/FSUB Q
FMUL/FDIV Q
FMIN-MAX
Q
FSQRT
Q

31

27 26

rs3
5
src3

13.3

fmt
2
Q

20 19

rs2
5
src2
src2
src2
0

25 24

15 14

rs1
5
src1
src1
src1
src

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

7 6

rm
rd
3
5
RM
dest
RM
dest
MIN/MAX dest
RM
dest

rm
3
RM

12 11

7 6

rd
5
dest

0

opcode
7
OP-FP
OP-FP
OP-FP
OP-FP

0

opcode7
F[N]MADD/F[N]MSUB

Quad-Precision Convert and Move Instructions

New floating-point-to-integer and integer-to-floating-point conversion instructions are added. These
instructions are defined analogously to the double-precision-to-integer and integer-to-doubleprecision conversion instructions. FCVT.W.Q or FCVT.L.Q converts a quad-precision floatingpoint number to a signed 32-bit or 64-bit integer, respectively. FCVT.Q.W or FCVT.Q.L converts a 32-bit or 64-bit signed integer, respectively, into a quad-precision floating-point number.
FCVT.WU.Q, FCVT.LU.Q, FCVT.Q.WU, and FCVT.Q.LU variants convert to or from unsigned
integer values. FCVT.L[U].Q and FCVT.Q.L[U] are RV64-only instructions.

Volume I: RISC-V Unprivileged ISA V20191213

31

27 26

funct5
5
FCVT.int.Q
FCVT.Q.int

25 24

fmt
2
Q
Q

20 19

rs2
5
W[U]/L[U]
W[U]/L[U]

81

15 14

rs1
5
src
src

12 11

rm
3
RM
RM

7 6

rd
5
dest
dest

0

opcode
7
OP-FP
OP-FP

New floating-point-to-floating-point conversion instructions are added. These instructions are defined analogously to the double-precision floating-point-to-floating-point conversion instructions.
FCVT.S.Q or FCVT.Q.S converts a quad-precision floating-point number to a single-precision
floating-point number, or vice-versa, respectively. FCVT.D.Q or FCVT.Q.D converts a quadprecision floating-point number to a double-precision floating-point number, or vice-versa, respectively.
31

27 26

funct5
5
FCVT.S.Q
FCVT.Q.SFCVT.D.Q
FCVT.Q.D

25 24

fmt
2
S
Q
D
Q

20 19

rs2
5
Q
S
Q
D

15 14

rs1
5
src
src
src
src

12 11

rm
3
RM
RM
RM
RM

7 6

rd
5
dest
dest
dest
dest

0

opcode
7
OP-FP
OP-FP
OP-FP
OP-FP

Floating-point to floating-point sign-injection instructions, FSGNJ.Q, FSGNJN.Q, and FSGNJX.Q
are defined analogously to the double-precision sign-injection instruction.
31

27 26

funct5
5
FSGNJ

25 24

fmt
2
Q

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

rm
3
J[N]/JX

7 6

rd
5
dest

0

opcode7
OP-FP

FMV.X.Q and FMV.Q.X instructions are not provided in RV32 or RV64, so quad-precision bit
patterns must be moved to the integer registers via memory.
RV128 will support FMV.X.Q and FMV.Q.X in the Q extension.

13.4

Quad-Precision Floating-Point Compare Instructions

The quad-precision floating-point compare instructions are defined analogously to their doubleprecision counterparts, but operate on quad-precision operands.
31

27 26

funct5
5
FCMP

fmt
2
Q

25 24

20 19

rs2
5
src2

15 14

rs1
5
src1

12 11

rm
rd
3
5
EQ/LT/LE dest

7 60

opcode
7
OP-FP

82

Volume I: RISC-V Unprivileged ISA V20191213

13.5

Quad-Precision Floating-Point Classify Instruction

The quad-precision floating-point classify instruction, FCLASS.Q, is defined analogously to its
double-precision counterpart, but operates on quad-precision operands.
31

27 26

funct5
5
FCLASS

fmt
2
Q

25 24

20 19

rs2
5
0

15 14

rs1
5
src

rm
3
001

12 11

7 6

rd
5
dest

0

opcode7
OP-FP

Chapter 14

RVWMO Memory Consistency
Model, Version 0.1
This chapter defines the RISC-V memory consistency model. A memory consistency model isa set of rules specifying the values that can be returned by loads of memory. RISC-V uses amemory model called “RVWMO” (RISC-V Weak Memory Ordering) which is designed to provide
flexibility for architects to build high-performance scalable designs while simultaneously supportinga tractable programming model.
Under RVWMO, code running on a single hart appears to execute in order from the perspectiveof other memory instructions in the same hart, but memory instructions from another hart may
observe the memory instructions from the first hart being executed in a different order. Therefore, multithreaded code may require explicit synchronization to guarantee ordering between memory instructions from different harts. The base RISC-V ISA provides a FENCE instruction forthis purpose, described in Section 2.7, while the atomics extension “A” additionally defines loadreserved/store-conditional and atomic read-modify-write instructions.
The standard ISA extension for misaligned atomics “Zam” (Chapter 22) and the standard ISA
extension for total store ordering “Ztso” (Chapter 23) augment RVWMO with additional rules
specific to those extensions.
The appendices to this specification provide both axiomatic and operational formalizations of thememory consistency model as well as additional explanatory material.
This chapter defines the memory model for regular main memory operations. The interactionof the memory model with I/O memory, instruction fetches, FENCE.I, page table walks, and
SFENCE.VMA is not (yet) formalized. Some or all of the above may be formalized in a futurerevision of this specification. The RV128 base ISA and future ISA extensions such as the “V”
vector, “T” transactional memory, and “J” JIT extensions will need to be incorporated into afuture revision as well.
Memory consistency models supporting overlapping memory accesses of different widths simultaneously remain an active area of academic research and are not yet fully understood. The
specifics of how memory accesses of different sizes interact under RVWMO are specified to thebest of our current abilities, but they are subject to revision should new issues be uncovered.

83

84

Volume I: RISC-V Unprivileged ISA V20191213

14.1

Definition of the RVWMO Memory Model

The RVWMO memory model is defined in terms of the global memory order, a total ordering of thememory operations produced by all harts. In general, a multithreaded program has many different
possible executions, with each execution having its own corresponding global memory order.
The global memory order is defined over the primitive load and store operations generated bymemory instructions. It is then subject to the constraints defined in the rest of this chapter. Any
execution satisfying all of the memory model constraints is a legal execution (as far as the memory
model is concerned).

Memory Model Primitives
The program order over memory operations reflects the order in which the instructions that generateeach load and store are logically laid out in that hart’s dynamic instruction stream; i.e., the orderin which a simple in-order processor would execute the instructions of that hart.
Memory-accessing instructions give rise to memory operations. A memory operation can be either
a load operation, a store operation, or both simultaneously. All memory operations are single-copy
atomic: they can never be observed in a partially-complete state.
Among instructions in RV32GC and RV64GC, each aligned memory instruction gives rise to exactly one memory operation, with two exceptions. First, an unsuccessful SC instruction does notgive rise to any memory operations. Second, FLD and FSD instructions may each give rise tomultiple memory operations if XLEN<64, as stated in Section 12.3 and clarified below. An aligned
AMO gives rise to a single memory operation that is both a load operation and a store operation
simultaneously.
Instructions in the RV128 base instruction set and in future ISA extensions such as V (vector)
and P (SIMD) may give rise to multiple memory operations. However, the memory model forthese extensions has not yet been formalized.

A misaligned load or store instruction may be decomposed into a set of component memory operations of any granularity. An FLD or FSD instruction for which XLEN<64 may also be decomposed
into a set of component memory operations of any granularity. The memory operations generated
by such instructions are not ordered with respect to each other in program order, but they areordered normally with respect to the memory operations generated by preceding and subsequent
instructions in program order. The atomics extension “A” does not require execution environments
to support misaligned atomic instructions at all; however, if misaligned atomics are supported via
the “Zam” extension, LRs, SCs, and AMOs may be decomposed subject to the constraints of theatomicity axiom for misaligned atomics, which is defined in Chapter 22.
The decomposition of misaligned memory operations down to byte granularity facilitates emulation on implementations that do not natively support misaligned accesses. Such implementations
might, for example, simply iterate over the bytes of a misaligned access one by one.

Volume I: RISC-V Unprivileged ISA V20191213

85

An LR instruction and an SC instruction are said to be paired if the LR precedes the SC in
program order and if there are no other LR or SC instructions in between; the corresponding
memory operations are said to be paired as well (except in case of a failed SC, where no store
operation is generated). The complete list of conditions determining whether an SC must succeed,
may succeed, or must fail is defined in Section 8.2.
Load and store operations may also carry one or more ordering annotations from the following set:“acquire-RCpc”, “acquire-RCsc”, “release-RCpc”, and “release-RCsc”. An AMO or LR instruction
with aq set has an “acquire-RCsc” annotation. An AMO or SC instruction with rl set has a “releaseRCsc” annotation. An AMO, LR, or SC instruction with both aq and rl set has both “acquire-RCsc”
and “release-RCsc” annotations.
For convenience, we use the term “acquire annotation” to refer to an acquire-RCpc annotation or an
acquire-RCsc annotation. Likewise, a “release annotation” refers to a release-RCpc annotation or arelease-RCsc annotation. An “RCpc annotation” refers to an acquire-RCpc annotation or a releaseRCpc annotation. An “RCsc annotation” refers to an acquire-RCsc annotation or a release-RCscannotation.
In the memory model literature, the term “RCpc” stands for release consistency with processorconsistent synchronization operations, and the term “RCsc” stands for release consistency withsequentially-consistent synchronization operations [5].
While there are many different definitions for acquire and release annotations in the literature, in the context of RVWMO these terms are concisely and completely defined by Preserved
Program Order rules 5–7.
“RCpc” annotations are currently only used when implicitly assigned to every memory access per the standard extension “Ztso” (Chapter 23). Furthermore, although the ISA does not
currently contain native load-acquire or store-release instructions, nor RCpc variants thereof,
the RVWMO model itself is designed to be forwards-compatible with the potential addition of
any or all of the above into the ISA in a future extension.

Syntactic Dependencies
The definition of the RVWMO memory model depends in part on the notion of a syntactic dependency, defined as follows.
In the context of defining dependencies, a “register” refers either to an entire general-purpose
register, some portion of a CSR, or an entire CSR. The granularity at which dependencies aretracked through CSRs is specific to each CSR and is defined in Section 14.2.
Syntactic dependencies are defined in terms of instructions’ source registers, instructions’ destination registers, and the way instructions carry a dependency from their source registers to theirdestination registers. This section provides a general definition of all of these terms; however,Section 14.3 provides a complete listing of the specifics for each instruction.
In general, a register r other than x0 is a source register for an instruction i if any of the following
hold:• In the opcode of i, rs1, rs2, or rs3 is set to r

86

Volume I: RISC-V Unprivileged ISA V20191213• i is a CSR instruction, and in the opcode of i, csr is set to r, unless i is CSRRW or CSRRWI
and rd is set to x0• r is a CSR and an implicit source register for i, as defined in Section 14.3
• r is a CSR that aliases with another source register for i

Memory instructions also further specify which source registers are address source registers andwhich are data source registers.
In general, a register r other than x0 is a destination register for an instruction i if any of thefollowing hold:• In the opcode of i, rd is set to r
• i is a CSR instruction, and in the opcode of i, csr is set to r, unless i is CSRRS or CSRRC
and rs1 is set to x0 or i is CSRRSI or CSRRCI and uimm[4:0] is set to zero.
• r is a CSR and an implicit destination register for i, as defined in Section 14.3
• r is a CSR that aliases with another destination register for i
Most non-memory instructions carry a dependency from each of their source registers to each of
their destination registers. However, there are exceptions to this rule; see Section 14.3
Instruction j has a syntactic dependency on instruction i via destination register s of i and source
register r of j if either of the following hold:• s is the same as r, and no instruction program-ordered between i and j has r as a destination
register• There is an instruction m program-ordered between i and j such that all of the following
hold:
1. j has a syntactic dependency on m via destination register q and source register r
2. m has a syntactic dependency on i via destination register s and source register p
3. m carries a dependency from p to q
Finally, in the definitions that follow, let a and b be two memory operations, and let i and j be theinstructions that generate a and b, respectively.
b has a syntactic address dependency on a if r is an address source register for j and j has a syntactic
dependency on i via source register rb has a syntactic data dependency on a if b is a store operation, r is a data source register for j,
and j has a syntactic dependency on i via source register rb has a syntactic control dependency on a if there is an instruction m program-ordered between iand j such that m is a branch or indirect jump and m has a syntactic dependency on i.

Volume I: RISC-V Unprivileged ISA V20191213

87

Generally speaking, non-AMO load instructions do not have data source registers, and unconditional non-AMO store instructions do not have destination registers. However, a successful SC
instruction is considered to have the register specified in rd as a destination register, and hence
it is possible for an instruction to have a syntactic dependency on a successful SC instructionthat precedes it in program order.

Preserved Program Order
The global memory order for any given execution of a program respects some but not all of eachhart’s program order. The subset of program order that must be respected by the global memoryorder is known as preserved program order.
The complete definition of preserved program order is as follows (and note that AMOs are simultaneously both loads and stores): memory operation a precedes memory operation b in preserved
program order (and hence also in the global memory order) if a precedes b in program order, a andb both access regular main memory (rather than I/O regions), and any of the following hold:• Overlapping-Address Orderings:
1. b is a store, and a and b access overlapping memory addresses
2. a and b are loads, x is a byte read by both a and b, there is no store to x between aand b in program order, and a and b return values for x written by different memory
operations
3. a is generated by an AMO or SC instruction, b is a load, and b returns a value written
by a• Explicit Synchronization
4. There is a FENCE instruction that orders a before b
5. a has an acquire annotation
6. b has a release annotation
7. a and b both have RCsc annotations
8. a is paired with b• Syntactic Dependencies
9. b has a syntactic address dependency on a
10. b has a syntactic data dependency on a
11. b is a store, and b has a syntactic control dependency on a
• Pipeline Dependencies
12. b is a load, and there exists some store m between a and b in program order such thatm has an address or data dependency on a, and b returns a value written by m
13. b is a store, and there exists some instruction m between a and b in program order suchthat m has an address dependency on a

88

Volume I: RISC-V Unprivileged ISA V20191213

Memory Model Axioms
An execution of a RISC-V program obeys the RVWMO memory consistency model only if there
exists a global memory order conforming to preserved program order and satisfying the load value
axiom, the atomicity axiom, and the progress axiom.

Load Value Axiom Each byte of each load i returns the value written to that byte by the store
that is the latest in global memory order among the following stores:
1. Stores that write that byte and that precede i in the global memory order
2. Stores that write that byte and that precede i in program order

Atomicity Axiom If r and w are paired load and store operations generated by aligned LR and
SC instructions in a hart h, s is a store to byte x, and r returns a value written by s, then s must
precede w in the global memory order, and there can be no store from a hart other than h to byte
x following s and preceding w in the global memory order.
The Atomicity Axiom theoretically supports LR/SC pairs of different widths and to mismatchedaddresses, since implementations are permitted to allow SC operations to succeed in such cases.
However, in practice, we expect such patterns to be rare, and their use is discouraged.

Progress Axiom No memory operation may be preceded in the global memory order by an
infinite sequence of other memory operations.

14.2

CSR Dependency Tracking Granularity
Namefflagsfrm
fcsr

Portions Tracked as Independent Units
Bits 4, 3, 2, 1, 0
entire CSR
Bits 7-5, 4, 3, 2, 1, 0

Aliases
fcsr
fcsr
fflags, frm

Table 14.1: Granularities at which syntactic dependencies are tracked through CSRs
Note: read-only CSRs are not listed, as they do not participate in the definition of syntactic
dependencies.

14.3

Source and Destination Register Listings

This section provides a concrete listing of the source and destination registers for each instruction.
These listings are used in the definition of syntactic dependencies in Section 14.1.

Volume I: RISC-V Unprivileged ISA V20191213

89

The term “accumulating CSR” is used to describe a CSR that is both a source and a destination
register, but which carries a dependency only from itself to itself.
Instructions carry a dependency from each source register in the “Source Registers” column to each
destination register in the “Destination Registers” column, from each source register in the “Source
Registers” column to each CSR in the “Accumulating CSRs” column, and from each CSR in the“Accumulating CSRs” column to itself, except where annotated otherwise.
Key:
A Address source register
D Data source register† The instruction does not carry a dependency from any source register to any destination register‡ The instruction carries dependencies from source register(s) to destination register(s) as specified

90

Volume I: RISC-V Unprivileged ISA V20191213

RV32I Base Integer Instruction Set
SourceDestination
Registers
Registers
LUI
rd
AUIPC
rd
JAL
rd
JALR†
rs1
rd
BEQ
rs1, rs2
BNE
rs1, rs2
BLT
rs1, rs2
BGE
rs1, rs2
BLTU
rs1, rs2
BGEU
rs1, rs2
†
LB
rs1A
rd
†
LH
rs1A
rd
†
A
LW
rs1
rd
LBU†
rs1A
rd
LHU†
rs1A
rd
A
D
SB
rs1 , rs2
SH
rs1A , rs2D
SW
rs1A , rs2D
ADDI
rs1
rd
SLTI
rs1
rd
SLTIU
rs1
rd
XORI
rs1
rd
ORI
rs1
rd
ANDI
rs1
rd
SLLI
rs1
rd
SRLI
rs1
rd
SRAI
rs1
rd
ADD
rs1, rs2rd
SUB
rs1, rs2rd
SLL
rs1, rs2rd
SLT
rs1, rs2
rd
SLTU
rs1, rs2
rd
XOR
rs1, rs2rd
SRL
rs1, rs2
rd
SRA
rs1, rs2rdOR
rs1, rs2rdAND
rs1, rs2rd
FENCE
FENCE.I
ECALL
EBREAK

Accumulating
CSRs

Volume I: RISC-V Unprivileged ISA V20191213

91

RV32I Base Integer Instruction Set (continued)
SourceDestination Accumulating
Registers
Registers
CSRs
CSRRW‡
rs1, csr∗rd, csrCSRRS‡
rs1, csrrd∗ , csr
CSRRC‡
rs1, csrrd∗ , csr
‡carries a dependency from rs1 to csr and from csr to rd∗ unless rd=x0

RV32I Base Integer Instruction Set (continued)
SourceDestination Accumulating
Registers
Registers
CSRs
CSRRWI‡
csr∗
rd, csrCSRRSI‡
csr
rd, csr∗‡
CSRRCI
csr
rd, csr∗‡carries a dependency from csr to rd∗ unless rd=x0

RV64I Base Integer Instruction Set
SourceDestination
Registers
Registers
†
A
LWU
rs1
rd
LD†
rs1A
rd
A
D
SD
rs1 , rs2
SLLI
rs1
rd
SRLI
rs1
rd
SRAI
rs1
rd
ADDIW
rs1
rd
SLLIW
rs1
rd
SRLIW
rs1
rd
SRAIW
rs1
rd
ADDW
rs1, rs2rd
SUBW
rs1, rs2rd
SLLW
rs1, rs2rd
SRLW
rs1, rs2
rd
SRAW
rs1, rs2rd
RV32M Standard Extension
SourceRegisters
MUL
rs1, rs2
MULH
rs1, rs2
MULHSUrs1, rs2
MULHU
rs1, rs2
DIV
rs1, rs2
DIVU
rs1, rs2
REM
rs1, rs2
REMU
rs1, rs2

Destination
Registers
rd
rd
rd
rd
rd
rd
rd
rd

Accumulating
CSRs

Accumulating
CSRs∗ unless rs1=x0∗ unless rs1=x0∗ unless uimm[4:0]=0∗ unless uimm[4:0]=0

92Volume I: RISC-V Unprivileged ISA V20191213

RV64M Standard Extension
SourceRegisters
MULW
rs1, rs2
DIVW
rs1, rs2
DIVUW
rs1, rs2
REMW
rs1, rs2
REMUW
rs1, rs2

Destination
Registers
rd
rd
rd
rd
rd

Accumulating
CSRs

RV32A Standard Extension
SourceRegisters
†
LR.W
rs1A
†
SC.W
rs1A , rs2D
AMOSWAP.W†
rs1A , rs2D†
AMOADD.W
rs1A , rs2D†
AMOXOR.W
rs1A , rs2D
AMOAND.W†
rs1A , rs2D†
AMOOR.W
rs1A , rs2D
AMOMIN.W†
rs1A , rs2D†
AMOMAX.W
rs1A , rs2D†
AMOMINU.W
rs1A , rs2D
AMOMAXU.W†
rs1A , rs2D

Destination
Registers
rd
rd∗
rd
rd
rd
rd
rd
rd
rd
rd
rd

Accumulating
CSRs

RV64A Standard Extension
SourceRegisters
LR.D†
rs1A
†
SC.D
rs1A , rs2D
AMOSWAP.D†
rs1A , rs2D†
AMOADD.D
rs1A , rs2D
AMOXOR.D†
rs1A , rs2D†
AMOAND.D
rs1A , rs2D†
AMOOR.D
rs1A , rs2D
AMOMIN.D†
rs1A , rs2D†
AMOMAX.D
rs1A , rs2D
AMOMINU.D†
rs1A , rs2D†
AMOMAXU.D
rs1A , rs2D

Destination
Registers
rd
rd∗
rd
rd
rd
rd
rd
rd
rd
rd
rd

Accumulating
CSRs∗ if successful∗ if successful

Volume I: RISC-V Unprivileged ISA V20191213
RV32F Standard Extension
SourceRegisters
FLW†
rs1A
FSW
rs1A , rs2D
FMADD.S
rs1, rs2, rs3, frm∗
FMSUB.S
rs1, rs2, rs3, frm∗
FNMSUB.S
rs1, rs2, rs3, frm∗
FNMADD.S
rs1, rs2, rs3, frm∗
FADD.S
rs1, rs2, frm∗
FSUB.S
rs1, rs2, frm∗
FMUL.S
rs1, rs2, frm∗
FDIV.S
rs1, rs2, frm∗
FSQRT.S
rs1, frm∗
FSGNJ.S
rs1, rs2
FSGNJN.S
rs1, rs2
FSGNJX.S
rs1, rs2
FMIN.S
rs1, rs2
FMAX.S
rs1, rs2
FCVT.W.S
rs1, frm∗
FCVT.WU.S
rs1, frm∗
FMV.X.W
rs1
FEQ.S
rs1, rs2
FLT.S
rs1, rs2
FLE.S
rs1, rs2
FCLASS.S
rs1
FCVT.S.W
rs1, frm∗
FCVT.S.WU
rs1, frm∗
FMV.W.X
rs1
RV64F Standard Extension
SourceRegisters
FCVT.L.S
rs1, frm∗
FCVT.LU.S
rs1, frm∗
FCVT.S.L
rs1, frm∗
FCVT.S.LU
rs1, frm∗

93

Destination
RegistersrdAccumulating
CSRs

rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd

NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, DZ, OF, UF, NX
NV, NX

Destination
Registers
rd
rd
rd
rd

Accumulating
CSRs
NV, NX
NV, NXNX
NXNVNV
NV, NX
NV, NX∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111

NV
NV
NV
NX
NX

∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111

94
RV32D Standard Extension
SourceRegisters
FLD†
rs1A
FSD
rs1A , rs2D
FMADD.D
rs1, rs2, rs3, frm∗
FMSUB.D
rs1, rs2, rs3, frm∗
FNMSUB.D
rs1, rs2, rs3, frm∗
FNMADD.D
rs1, rs2, rs3, frm∗
FADD.D
rs1, rs2, frm∗
FSUB.D
rs1, rs2, frm∗
FMUL.D
rs1, rs2, frm∗
FDIV.D
rs1, rs2, frm∗
FSQRT.D
rs1, frm∗
FSGNJ.D
rs1, rs2
FSGNJN.D
rs1, rs2
FSGNJX.D
rs1, rs2
FMIN.D
rs1, rs2
FMAX.D
rs1, rs2
FCVT.S.D
rs1, frm∗
FCVT.D.S
rs1, frm∗
FEQ.D
rs1, rs2
FLT.D
rs1, rs2
FLE.D
rs1, rs2
FCLASS.D
rs1
FCVT.W.D
rs1, frm∗
FCVT.WU.D
rs1, frm∗
FCVT.D.W
rs1
FCVT.D.WU
rs1
RV64D Standard Extension
SourceRegisters
FCVT.L.D
rs1, frm∗
FCVT.LU.D
rs1, frm∗
FMV.X.D
rs1
FCVT.D.L
rs1, frm∗
FCVT.D.LU
rs1, frm∗
FMV.D.X
rs1

Volume I: RISC-V Unprivileged ISA V20191213

Destination
RegistersrdAccumulating
CSRs

rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd

NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, OF, UF, NX
NV, DZ, OF, UF, NX
NV, NX

Destination
Registers
rd
rd
rd
rd
rd
rd

Accumulating
CSRs
NV, NX
NV, NX

NV
NV
NX
NX
NV
NV
NV
NV, NX
NV, NX

NX
NX∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111∗ if rm=111

Chapter 15“L” Standard Extension for Decimal
Floating-Point, Version 0.0
This chapter is a draft proposal that has not been ratified by the Foundation.
This chapter is a placeholder for the specification of a standard extension named “L” designed tosupport decimal floating-point arithmetic as defined in the IEEE 754-2008 standard.

15.1

Decimal Floating-Point Registers

Existing floating-point registers are used to hold 64-bit and 128-bit decimal floating-point values,
and the existing floating-point load and store instructions are used to move values to and frommemory.
Due to the large opcode space required by the fused multiply-add instructions, the decimal floatingpoint instruction extension will require five 25-bit major opcodes in a 30-bit encoding space.

95

96

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 16“C” Standard Extension for
Compressed Instructions, Version 2.0
This chapter describes the current proposal for the RISC-V standard compressed instruction-set
extension, named “C”, which reduces static and dynamic code size by adding short 16-bit instruction
encodings for common operations. The C extension can be added to any of the base ISAs (RV32,
RV64, RV128), and we use the generic term “RVC” to cover any of these. Typically, 50%–60%of the RISC-V instructions in a program can be replaced with RVC instructions, resulting in a
25%–30% code-size reduction.

16.1

Overview

RVC uses a simple compression scheme that offers shorter 16-bit versions of common 32-bit RISC-V
instructions when:• the immediate or address offset is small, or• one of the registers is the zero register (x0), the ABI link register (x1), or the ABI stack
pointer (x2), or• the destination register and the first source register are identical, or• the registers used are the 8 most popular ones.
The C extension is compatible with all other standard instruction extensions. The C extension
allows 16-bit instructions to be freely intermixed with 32-bit instructions, with the latter now able
to start on any 16-bit boundary, i.e., IALIGN=16. With the addition of the C extension, no
instructions can raise instruction-address-misaligned exceptions.
Removing the 32-bit alignment constraint on the original 32-bit instructions allows significantly
greater code density.

The compressed instruction encodings are mostly common across RV32C, RV64C, and RV128C,
but as shown in Table 16.4, a few opcodes are used for different purposes depending on base
ISA width. For example, the wider address-space RV64C and RV128C variants require additional97

98

Volume I: RISC-V Unprivileged ISA V20191213

opcodes to compress loads and stores of 64-bit integer values, while RV32C uses the same opcodes
to compress loads and stores of single-precision floating-point values. Similarly, RV128C requires
additional opcodes to capture loads and stores of 128-bit integer values, while these same opcodes
are used for loads and stores of double-precision floating-point values in RV32C and RV64C. If theC extension is implemented, the appropriate compressed floating-point load and store instructions
must be provided whenever the relevant standard floating-point extension (F and/or D) is also
implemented. In addition, RV32C includes a compressed jump and link instruction to compress
short-range subroutine calls, where the same opcode is used to compress ADDIW for RV64C and
RV128C.
Double-precision loads and stores are a significant fraction of static and dynamic instructions,hence the motivation to include them in the RV32C and RV64C encoding.
Although single-precision loads and stores are not a significant source of static or dynamic
compression for benchmarks compiled for the currently supported ABIs, for microcontrollers
that only provide hardware single-precision floating-point units and have an ABI that only supports single-precision floating-point numbers, the single-precision loads and stores will be used
at least as frequently as double-precision loads and stores in the measured benchmarks. Hence,
the motivation to provide compressed support for these in RV32C.
Short-range subroutine calls are more likely in small binaries for microcontrollers, hence themotivation to include these in RV32C.
Although reusing opcodes for different purposes for different base register widths adds somecomplexity to documentation, the impact on implementation complexity is small even for designs
that support multiple base ISA register widths. The compressed floating-point load and store
variants use the same instruction format with the same register specifiers as the wider integerloads and stores.

RVC was designed under the constraint that each RVC instruction expands into a single 32-bit
instruction in either the base ISA (RV32I/E, RV64I, or RV128I) or the F and D standard extensions
where present. Adopting this constraint has two main benefits:• Hardware designs can simply expand RVC instructions during decode, simplifying verificationand minimizing modifications to existing microarchitectures.
• Compilers can be unaware of the RVC extension and leave code compression to the assembler
and linker, although a compression-aware compiler will generally be able to produce better
results.
We felt the multiple complexity reductions of a simple one-one mapping between C and base
IFD instructions far outweighed the potential gains of a slightly denser encoding that added
additional instructions only supported in the C extension, or that allowed encoding of multiple
IFD instructions in one C instruction.

It is important to note that the C extension is not designed to be a stand-alone ISA, and is meant
to be used alongside a base ISA.
Variable-length instruction sets have long been used to improve code density. For example, theIBM Stretch [4], developed in the late 1950s, had an ISA with 32-bit and 64-bit instructions,where some of the 32-bit instructions were compressed versions of the full 64-bit instructions.
Stretch also employed the concept of limiting the set of registers that were addressable in someof the shorter instruction formats, with short branch instructions that could only refer to one

Volume I: RISC-V Unprivileged ISA V20191213

99of the index registers. The later IBM 360 architecture [3] supported a simple variable-length
instruction encoding with 16-bit, 32-bit, or 48-bit instruction formats.
In 1963, CDC introduced the Cray-designed CDC 6600 [18], a precursor to RISC architectures, that introduced a register-rich load-store architecture with instructions of two lengths,
15-bits and 30-bits. The later Cray-1 design used a very similar instruction format, with 16-bit
and 32-bit instruction lengths.
The initial RISC ISAs from the 1980s all picked performance over code size, which wasreasonable for a workstation environment, but not for embedded systems. Hence, both ARM
and MIPS subsequently made versions of the ISAs that offered smaller code size by offering analternative 16-bit wide instruction set instead of the standard 32-bit wide instructions. The compressed RISC ISAs reduced code size relative to their starting points by about 25–30%, yieldingcode that was significantly smaller than 80x86. This result surprised some, as their intuition
was that the variable-length CISC ISA should be smaller than RISC ISAs that offered only 16-bit
and 32-bit formats.
Since the original RISC ISAs did not leave sufficient opcode space free to include these
unplanned compressed instructions, they were instead developed as complete new ISAs. This
meant compilers needed different code generators for the separate compressed ISAs. The firstcompressed RISC ISA extensions (e.g., ARM Thumb and MIPS16) used only a fixed 16-bit instruction size, which gave good reductions in static code size but caused an increase in dynamic
instruction count, which led to lower performance compared to the original fixed-width 32-bit
instruction size. This led to the development of a second generation of compressed RISC ISA
designs with mixed 16-bit and 32-bit instruction lengths (e.g., ARM Thumb2, microMIPS, PowerPC VLE), so that performance was similar to pure 32-bit instructions but with significant
code size savings. Unfortunately, these different generations of compressed ISAs are incompatible with each other and with the original uncompressed ISA, leading to significant complexity indocumentation, implementations, and software tools support.
Of the commonly used 64-bit ISAs, only PowerPC and microMIPS currently supports acompressed instruction format. It is surprising that the most popular 64-bit ISA for mobile
platforms (ARM v8) does not include a compressed instruction format given that static code
size and dynamic instruction fetch bandwidth are important metrics. Although static code size
is not a major concern in larger systems, instruction fetch bandwidth can be a major bottleneckin servers running commercial workloads, which often have a large instruction working set.
Benefiting from 25 years of hindsight, RISC-V was designed to support compressed instructions from the outset, leaving enough opcode space for RVC to be added as a simple extension
on top of the base ISA (along with many other extensions). The philosophy of RVC is to reduce
code size for embedded applications and to improve performance and energy-efficiency for all
applications due to fewer misses in the instruction cache. Waterman shows that RVC fetches
25%-30% fewer instruction bits, which reduces instruction cache misses by 20%-25%, or roughly
the same performance impact as doubling the instruction cache size [22].

16.2

Compressed Instruction Formats

Table 16.1 shows the nine compressed instruction formats. CR, CI, and CSS can use any of the 32
RVI registers, but CIW, CL, CS, CA, and CB are limited to just 8 of them. Table 16.2 lists these
popular registers, which correspond to registers x8 to x15. Note that there is a separate version ofload and store instructions that use the stack pointer as the base address register, since saving toand restoring from the stack are so prevalent, and that they use the CI and CSS formats to allow
access to all 32 data registers. CIW supplies an 8-bit immediate for the ADDI4SPN instruction.

100

Volume I: RISC-V Unprivileged ISA V20191213

The RISC-V ABI was changed to make the frequently used registers map to registers x8–x15.
This simplifies the decompression decoder by having a contiguous naturally aligned set of register
numbers, and is also compatible with the RV32E base ISA, which only has 16 integer registers.

Compressed register-based floating-point loads and stores also use the CL and CS formats respectively, with the eight registers mapping to f8 to f15.
The standard RISC-V calling convention maps the most frequently used floating-point registers
to registers f8 to f15, which allows the same register decompression decoding as for integer
register numbers.

The formats were designed to keep bits for the two register source specifiers in the same place in all
instructions, while the destination register field can move. When the full 5-bit destination register
specifier is present, it is in the same place as in the 32-bit RISC-V encoding. Where immediates
are sign-extended, the sign-extension is always from bit 12. Immediate fields have been scrambled,
as in the base specification, to reduce the number of immediate muxes required.
The immediate fields are scrambled in the instruction formats instead of in sequential order sothat as many bits as possible are in the same position in every instruction, thereby simplifying implementations. For example, immediate bits 17—10 are always sourced from the same
instruction bit positions. Five other immediate bits (5, 4, 3, 1, and 0) have just two source
instruction bits, while four (9, 7, 6, and 2) have three sources and one (8) has four sources.

For many RVC instructions, zero-valued immediates are disallowed and x0 is not a valid 5-bit
register specifier. These restrictions free up encoding space for other instructions requiring fewer
operand bits.
Format
CR
CI
CSS
CIW
CL
CS
CA
CB
CJ

Meaning
Register
Immediate
Stack-relative Store
Wide Immediate
Load
Store
Arithmetic
BranchJump

15 14 1312

11 10 9

8

7

6

5

4

3

2

funct4
rd/rs1rs2funct3 imm
rd/rs1imm
funct3imm
rs2
funct3imm
rd ′′funct3
imm
rs1
imm
rd ′
′
funct3
imm
rs1
imm
rs2 ′
′
′
funct6rd /rs1funct2rs2 ′′funct3
offsetrs1
offsetfunct3jump target

1

0

op
op
op
op
op
op
op
op
op

Table 16.1: Compressed 16-bit RVC instruction formats.
RVC Register Number
Integer Register Number
Integer Register ABI Name
Floating-Point Register Number
Floating-Point Register ABI Name

000
x8
s0
f8
fs0

001
x9
s1
f9
fs1

010
x10
a0
f10
fa0

011
x11
a1
f11
fa1

100
x12
a2
f12
fa2

101
x13
a3
f13
fa3

110
x14
a4
f14
fa4

111
x15
a5
f15
fa5

Table 16.2: Registers specified by the three-bit rs1 ′ , rs2 ′ , and rd ′ fields of the CIW, CL, CS, CA,
and CB formats.

Volume I: RISC-V Unprivileged ISA V20191213

16.3

101

Load and Store Instructions

To increase the reach of 16-bit instructions, data-transfer instructions use zero-extended immediatesthat are scaled by the size of the data in bytes: ×4 for words, ×8 for double words, and ×16 forquad words.
RVC provides two variants of loads and stores. One uses the ABI stack pointer, x2, as the baseaddress and can target any data register. The other can reference one of 8 base address registers
and one of 8 data registers.

Stack-Pointer-Based Loads and Stores

15

13

funct3
3
C.LWSP
C.LDSP
C.LQSP
C.FLWSP
C.FLDSP

12

11

imm
1
offset[5]offset[5]offset[5]offset[5]offset[5]

7 6

rd
5
dest̸=0dest̸=0dest̸=0
dest
dest

2 1

imm
5
offset[4:2|7:6]
offset[4:3|8:6]
offset[4|9:6]
offset[4:2|7:6]
offset[4:3|8:6]

0

op
2
C2
C2
C2
C2
C2

These instructions use the CI format.
C.LWSP loads a 32-bit value from memory into register rd. It computes an effective addressby adding the zero-extended offset, scaled by 4, to the stack pointer, x2. It expands to lw rd,offset[7:2](x2). C.LWSP is only valid when rd̸=x0; the code points with rd=x0 are reserved.
C.LDSP is an RV64C/RV128C-only instruction that loads a 64-bit value from memory into register
rd. It computes its effective address by adding the zero-extended offset, scaled by 8, to the stack
pointer, x2. It expands to ld rd, offset[8:3](x2). C.LDSP is only valid when rd̸=x0; the code
points with rd=x0 are reserved.
C.LQSP is an RV128C-only instruction that loads a 128-bit value from memory into register rd. It
computes its effective address by adding the zero-extended offset, scaled by 16, to the stack pointer,x2. It expands to lq rd, offset[9:4](x2). C.LQSP is only valid when rd̸=x0; the code points
with rd=x0 are reserved.
C.FLWSP is an RV32FC-only instruction that loads a single-precision floating-point value frommemory into floating-point register rd. It computes its effective address by adding the zero-extended
offset, scaled by 4, to the stack pointer, x2. It expands to flw rd, offset[7:2](x2).
C.FLDSP is an RV32DC/RV64DC-only instruction that loads a double-precision floating-pointvalue from memory into floating-point register rd. It computes its effective address by adding
the zero-extended offset, scaled by 8, to the stack pointer, x2. It expands to fld rd,offset[8:3](x2).

102Volume I: RISC-V Unprivileged ISA V20191213

15

13 12

funct3
3
C.SWSP
C.SDSPC.SQSP
C.FSWSP
C.FSDSP

7 6

imm
6
offset[5:2|7:6]
offset[5:3|8:6]
offset[5:4|9:6]
offset[5:2|7:6]
offset[5:3|8:6]

2 1

rs2
5
src
src
src
src
src

0

op
2
C2
C2
C2
C2
C2

These instructions use the CSS format.
C.SWSP stores a 32-bit value in register rs2 to memory. It computes an effective address byadding the zero-extended offset, scaled by 4, to the stack pointer, x2. It expands to sw rs2,
offset[7:2](x2).
C.SDSP is an RV64C/RV128C-only instruction that stores a 64-bit value in register rs2 to memory.
It computes an effective address by adding the zero-extended offset, scaled by 8, to the stack pointer,x2. It expands to sd rs2, offset[8:3](x2).
C.SQSP is an RV128C-only instruction that stores a 128-bit value in register rs2 to memory. It
computes an effective address by adding the zero-extended offset, scaled by 16, to the stack pointer,x2. It expands to sq rs2, offset[9:4](x2).
C.FSWSP is an RV32FC-only instruction that stores a single-precision floating-point value infloating-point register rs2 to memory. It computes an effective address by adding the zero-extended
offset, scaled by 4, to the stack pointer, x2. It expands to fsw rs2, offset[7:2](x2).
C.FSDSP is an RV32DC/RV64DC-only instruction that stores a double-precision floating-pointvalue in floating-point register rs2 to memory. It computes an effective address by adding the zeroextended offset, scaled by 8, to the stack pointer, x2. It expands to fsd rs2, offset[8:3](x2).
Register save/restore code at function entry/exit represents a significant portion of static codesize. The stack-pointer-based compressed loads and stores in RVC are effective at reducing thesave/restore static code size by a factor of 2 while improving performance by reducing dynamic
instruction bandwidth.
A common mechanism used in other ISAs to further reduce save/restore code size is loadmultiple and store-multiple instructions. We considered adopting these for RISC-V but noted
the following drawbacks to these instructions:• These instructions complicate processor implementations.
• For virtual memory systems, some data accesses could be resident in physical memory andsome could not, which requires a new restart mechanism for partially executed instructions.
• Unlike the rest of the RVC instructions, there is no IFD equivalent to Load Multiple andStore Multiple.
• Unlike the rest of the RVC instructions, the compiler would have to be aware of these
instructions to both generate the instructions and to allocate registers in an order to maximize the chances of the them being saved and stored, since they would be saved and restored
in sequential order.

Volume I: RISC-V Unprivileged ISA V20191213

103• Simple microarchitectural implementations will constrain how other instructions can bescheduled around the load and store multiple instructions, leading to a potential performance loss.
• The desire for sequential register allocation might conflict with the featured registers selected
for the CIW, CL, CS, CA, and CB formats.
Furthermore, much of the gains can be realized in software by replacing prologue and epilogue
code with subroutine calls to common prologue and epilogue code, a technique described in Section
5.6 of [23].
While reasonable architects might come to different conclusions, we decided to omit loadand store multiple and instead use the software-only approach of calling save/restore millicode
routines to attain the greatest code size reduction.

Register-Based Loads and Stores

15

13 12

funct3
3
C.LW
C.LD
C.LQ
C.FLW
C.FLD

10 9

imm
3
offset[5:3]
offset[5:3]
offset[5|4|8]
offset[5:3]
offset[5:3]

7 6

rs1 ′
3
base
base
base
base
base

5 4

imm
2
offset[2|6]offset[7:6]
offset[7:6]
offset[2|6]offset[7:6]

2 1

rd ′
3
dest
dest
dest
dest
dest

0

op
2
C0
C0
C0
C0
C0

These instructions use the CL format.
C.LW loads a 32-bit value from memory into register rd ′ . It computes an effective address byadding the zero-extended offset, scaled by 4, to the base address in register rs1 ′ . It expands to lwrd ′ , offset[6:2](rs1 ′ ).
C.LD is an RV64C/RV128C-only instruction that loads a 64-bit value from memory into registerrd ′ . It computes an effective address by adding the zero-extended offset, scaled by 8, to the baseaddress in register rs1 ′ . It expands to ld rd ′ , offset[7:3](rs1 ′ ).
C.LQ is an RV128C-only instruction that loads a 128-bit value from memory into register rd ′ . It
computes an effective address by adding the zero-extended offset, scaled by 16, to the base address
in register rs1 ′ . It expands to lq rd ′ , offset[8:4](rs1 ′ ).
C.FLW is an RV32FC-only instruction that loads a single-precision floating-point value from memory into floating-point register rd ′ . It computes an effective address by adding the zero-extended
offset, scaled by 4, to the base address in register rs1 ′ . It expands to flw rd ′ , offset[6:2](rs1 ′ ).
C.FLD is an RV32DC/RV64DC-only instruction that loads a double-precision floating-point value
from memory into floating-point register rd ′ . It computes an effective address by adding thezero-extended offset, scaled by 8, to the base address in register rs1 ′ . It expands to fld rd ′ ,offset[7:3](rs1 ′ ).

104

Volume I: RISC-V Unprivileged ISA V20191213

15

13 12

funct3
3
C.SW
C.SD
C.SQ
C.FSW
C.FSD

10 9

imm
3
offset[5:3]
offset[5:3]
offset[5|4|8]
offset[5:3]
offset[5:3]

7 6

rs1 ′
3
base
base
base
base
base

5 4

imm
2
offset[2|6]offset[7:6]
offset[7:6]
offset[2|6]offset[7:6]

2 1

rs2 ′

0

op
2
C0
C0
C0
C0
C0

3
src
src
src
src
src

These instructions use the CS format.
C.SW stores a 32-bit value in register rs2 ′ to memory. It computes an effective address by adding
the zero-extended offset, scaled by 4, to the base address in register rs1 ′ . It expands to sw rs2 ′ ,offset[6:2](rs1 ′ ).
C.SD is an RV64C/RV128C-only instruction that stores a 64-bit value in register rs2 ′ to memory.
It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address
in register rs1 ′ . It expands to sd rs2 ′ , offset[7:3](rs1 ′ ).
C.SQ is an RV128C-only instruction that stores a 128-bit value in register rs2 ′ to memory. It
computes an effective address by adding the zero-extended offset, scaled by 16, to the base address
in register rs1 ′ . It expands to sq rs2 ′ , offset[8:4](rs1 ′ ).
C.FSW is an RV32FC-only instruction that stores a single-precision floating-point value in floatingpoint register rs2 ′ to memory. It computes an effective address by adding the zero-extended offset,
scaled by 4, to the base address in register rs1 ′ . It expands to fsw rs2 ′ , offset[6:2](rs1 ′ ).
C.FSD is an RV32DC/RV64DC-only instruction that stores a double-precision floating-point value
in floating-point register rs2 ′ to memory. It computes an effective address by adding the zeroextended offset, scaled by 8, to the base address in register rs1 ′ . It expands to fsd rs2 ′ ,offset[7:3](rs1 ′ ).

16.4

Control Transfer Instructions

RVC provides unconditional jump instructions and conditional branch instructions. As with base
RVI instructions, the offsets of all RVC control transfer instruction are in multiples of 2 bytes.

15

13 12

funct3
3
C.J
C.JAL
These instructions use the CJ format.

2 1

imm
11
offset[11|4|9:8|10|6|7|3:1|5]
offset[11|4|9:8|10|6|7|3:1|5]

0

op
2
C1
C1

Volume I: RISC-V Unprivileged ISA V20191213

105

C.J performs an unconditional control transfer. The offset is sign-extended and added to the pc toform the jump target address. C.J can therefore target a ±2 KiB range. C.J expands to jal x0,
offset[11:1].
C.JAL is an RV32C-only instruction that performs the same operation as C.J, but additionally
writes the address of the instruction following the jump (pc+2) to the link register, x1. C.JAL
expands to jal x1, offset[11:1].

15

12 11

funct4
4
C.JR
C.JALR

7 6

rs1
5
src̸=0src̸=0

2 1

rs2
5
0
0

0

op
2
C2
C2

These instructions use the CR format.
C.JR (jump register) performs an unconditional control transfer to the address in register rs1.
C.JR expands to jalr x0, 0(rs1). C.JR is only valid when rs1̸=x0; the code point with rs1=x0
is reserved.
C.JALR (jump and link register) performs the same operation as C.JR, but additionally writes theaddress of the instruction following the jump (pc+2) to the link register, x1. C.JALR expands tojalr x1, 0(rs1). C.JALR is only valid when rs1̸=x0; the code point with rs1=x0 corresponds
to the C.EBREAK instruction.
Strictly speaking, C.JALR does not expand exactly to a base RVI instruction as the value added
to the PC to form the link address is 2 rather than 4 as in the base ISA, but supporting bothoffsets of 2 and 4 bytes is only a very minor change to the base microarchitecture.

15

13 12

funct3
3
C.BEQZ
C.BNEZ

10 9

imm
3
offset[8|4:3]
offset[8|4:3]

7 6

rs1 ′
3
src
src

2 1

imm
5
offset[7:6|2:1|5]
offset[7:6|2:1|5]

0

op
2
C1
C1

These instructions use the CB format.
C.BEQZ performs conditional control transfers. The offset is sign-extended and added to the pc toform the branch target address. It can therefore target a ±256 B range. C.BEQZ takes the branch
if the value in register rs1 ′ is zero. It expands to beq rs1 ′ , x0, offset[8:1].
C.BNEZ is defined analogously, but it takes the branch if rs1 ′ contains a nonzero value. It expands
to bne rs1 ′ , x0, offset[8:1].

106

Volume I: RISC-V Unprivileged ISA V20191213

16.5

Integer Computational Instructions

RVC provides several instructions for integer arithmetic and constant generation.

Integer Constant-Generation Instructions
The two constant-generation instructions both use the CI instruction format and can target any
integer register.
15

13

funct3
3
C.LI
C.LUI

12

11

imm[5]
1
imm[5]
nzimm[17]

7 6

rd
5
dest̸=0dest̸={0, 2}

2 1

imm[4:0]5
imm[4:0]nzimm[16:12]

0

op
2
C1
C1

C.LI loads the sign-extended 6-bit immediate, imm, into register rd. C.LI expands into addi rd,x0, imm[5:0]. C.LI is only valid when rd̸=x0; the code points with rd=x0 encode HINTs.
C.LUI loads the non-zero 6-bit immediate field into bits 17–12 of the destination register, clears thebottom 12 bits, and sign-extends bit 17 into all higher bits of the destination. C.LUI expands into
lui rd, nzimm[17:12]. C.LUI is only valid when rd̸={x0, x2}, and when the immediate is notequal to zero. The code points with nzimm=0 are reserved; the remaining code points with rd=x0
are HINTs; and the remaining code points with rd=x2 correspond to the C.ADDI16SP instruction.

Integer Register-Immediate Operations
These integer register-immediate operations are encoded in the CI format and perform operations
on an integer register and a 6-bit immediate.
15

13

12

funct3
imm[5]
3
1
C.ADDI
nzimm[5]C.ADDIW imm[5]C.ADDI16SP nzimm[9]

11

7 6

rd/rs15dest̸=0dest̸=02

2 1

imm[4:0]
5nzimm[4:0]
imm[4:0]nzimm[4|6|8:7|5]

0

op
2
C1
C1
C1

C.ADDI adds the non-zero sign-extended 6-bit immediate to the value in register rd then writes
the result to rd. C.ADDI expands into addi rd, rd, nzimm[5:0]. C.ADDI is only valid whenrd̸=x0 and nzimm̸=0. The code points with rd=x0 encode the C.NOP instruction; the remaining
code points with nzimm=0 encode HINTs.
C.ADDIW is an RV64C/RV128C-only instruction that performs the same computation but produces a 32-bit result, then sign-extends result to 64 bits. C.ADDIW expands into addiw rd,rd, imm[5:0]. The immediate can be zero for C.ADDIW, where this corresponds to sext.w rd.
C.ADDIW is only valid when rd̸=x0; the code points with rd=x0 are reserved.

Volume I: RISC-V Unprivileged ISA V20191213

107

C.ADDI16SP shares the opcode with C.LUI, but has a destination field of x2. C.ADDI16SP adds
the non-zero sign-extended 6-bit immediate to the value in the stack pointer (sp=x2), where theimmediate is scaled to represent multiples of 16 in the range (-512,496). C.ADDI16SP is used
to adjust the stack pointer in procedure prologues and epilogues. It expands into addi x2, x2,
nzimm[9:4]. C.ADDI16SP is only valid when nzimm̸=0; the code point with nzimm=0 is reserved.
In the standard RISC-V calling convention, the stack pointer sp is always 16-byte aligned.

15

13 12

5 4

funct3
3
C.ADDI4SPN

2 1

rd ′

imm
8
nzuimm[5:4|9:6|2|3]

3
dest

0

op
2
C0

C.ADDI4SPN is a CIW-format instruction that adds a zero-extended non-zero immediate, scaledby 4, to the stack pointer, x2, and writes the result to rd ′ . This instruction is used to generate
pointers to stack-allocated variables, and expands to addi rd ′ , x2, nzuimm[9:2]. C.ADDI4SPN
is only valid when nzuimm̸=0; the code points with nzuimm=0 are reserved.
15

13

funct3
3
C.SLLI

12

11

7 6

shamt[5]1
shamt[5]rd/rs15dest̸=0

2 1

shamt[4:0]5shamt[4:0]

0

op
2
C2

C.SLLI is a CI-format instruction that performs a logical left shift of the value in register rd thenwrites the result to rd. The shift amount is encoded in the shamt field. For RV128C, a shift amountof zero is used to encode a shift of 64. C.SLLI expands into slli rd, rd, shamt[5:0], except for
RV128C with shamt=0, which expands to slli rd, rd, 64.
For RV32C, shamt[5] must be zero; the code points with shamt[5]=1 are reserved for custom
extensions. For RV32C and RV64C, the shift amount must be non-zero; the code points withshamt=0 are HINTs. For all base ISAs, the code points with rd=x0 are HINTs, except those withshamt[5]=1 in RV32C.
15

13

funct3
3
C.SRLIC.SRAI12

shamt[5]1
shamt[5]shamt[5]11

10 9funct2
2
C.SRLIC.SRAI7 6rd ′ /rs1 ′
3
dest
dest

2 1

shamt[4:0]5shamt[4:0]
shamt[4:0]

0

op
2
C1
C1

C.SRLI is a CB-format instruction that performs a logical right shift of the value in register rd ′then writes the result to rd ′ . The shift amount is encoded in the shamt field. For RV128C, a shift
amount of zero is used to encode a shift of 64. Furthermore, the shift amount is sign-extended for
RV128C, and so the legal shift amounts are 1–31, 64, and 96–127. C.SRLI expands into srli rd ′ ,rd ′ , shamt[5:0], except for RV128C with shamt=0, which expands to srli rd ′ , rd ′ , 64.
For RV32C, shamt[5] must be zero; the code points with shamt[5]=1 are reserved for custom
extensions. For RV32C and RV64C, the shift amount must be non-zero; the code points withshamt=0 are HINTs.

108

Volume I: RISC-V Unprivileged ISA V20191213

C.SRAI is defined analogously to C.SRLI, but instead performs an arithmetic right shift. C.SRAI
expands to srai rd ′ , rd ′ , shamt[5:0].
Left shifts are usually more frequent than right shifts, as left shifts are frequently used to scale
address values. Right shifts have therefore been granted less encoding space and are placed in
an encoding quadrant where all other immediates are sign-extended. For RV128, the decision
was made to have the 6-bit shift-amount immediate also be sign-extended. Apart from reducing
the decode complexity, we believe right-shift amounts of 96–127 will be more useful than 64–95,
to allow extraction of tags located in the high portions of 128-bit address pointers. We notethat RV128C will not be frozen at the same point as RV32C and RV64C, to allow evaluation of
typical usage of 128-bit address-space codes.

15

13funct3
3
C.ANDI1211

imm[5]
1
imm[5]

10 9funct2
2
C.ANDI7 6rd ′ /rs1 ′
3
dest

2 1

imm[4:0]5
imm[4:0]

0

op
2
C1

C.ANDI is a CB-format instruction that computes the bitwise AND of the value in register rd ′ andthe sign-extended 6-bit immediate, then writes the result to rd ′ . C.ANDI expands to andi rd ′ ,rd ′ , imm[5:0].

Integer Register-Register Operations
15

12 11

funct4
4
C.MV
C.ADD

7 6

rd/rs15dest̸=0dest̸=02 1

rs2
5src̸=0src̸=0

0

op
2
C2
C2

These instructions use the CR format.
C.MV copies the value in register rs2 into register rd. C.MV expands into add rd, x0, rs2. C.MV
is only valid when rs2̸=x0; the code points with rs2=x0 correspond to the C.JR instruction. The
code points with rs2̸=x0 and rd=x0 are HINTs.
C.MV expands to a different instruction than the canonical MV pseudoinstruction, which instead
uses ADDI. Implementations that handle MV specially, e.g. using register-renaming hardware,
may find it more convenient to expand C.MV to MV instead of ADD, at slight additional hardware cost.

C.ADD adds the values in registers rd and rs2 and writes the result to register rd. C.ADD expands
into add rd, rd, rs2. C.ADD is only valid when rs2̸=x0; the code points with rs2=x0 correspondto the C.JALR and C.EBREAK instructions. The code points with rs2̸=x0 and rd=x0 are HINTs.

Volume I: RISC-V Unprivileged ISA V20191213

15

10 9

7 6

rd ′ /rs1 ′funct6
6
C.AND
C.OR
C.XOR
C.SUB
C.ADDW
C.SUBW

109

3
dest
dest
dest
dest
dest
dest

5 4

2 1

rs2 ′

funct2
2
C.AND
C.OR
C.XOR
C.SUB
C.ADDW
C.SUBW

0

op
2
C1
C1
C1
C1
C1
C1

3
src
src
src
src
src
src

These instructions use the CA format.
C.AND computes the bitwise AND of the values in registers rd ′ and rs2 ′ , then writes the result toregister rd ′ . C.AND expands into and rd ′ , rd ′ , rs2 ′ .
C.OR computes the bitwise OR of the values in registers rd ′ and rs2 ′ , then writes the result toregister rd ′ . C.OR expands into or rd ′ , rd ′ , rs2 ′ .
C.XOR computes the bitwise XOR of the values in registers rd ′ and rs2 ′ , then writes the result toregister rd ′ . C.XOR expands into xor rd ′ , rd ′ , rs2 ′ .
C.SUB subtracts the value in register rs2 ′ from the value in register rd ′ , then writes the result toregister rd ′ . C.SUB expands into sub rd ′ , rd ′ , rs2 ′ .
C.ADDW is an RV64C/RV128C-only instruction that adds the values in registers rd ′ and rs2 ′ ,then sign-extends the lower 32 bits of the sum before writing the result to register rd ′ . C.ADDW
expands into addw rd ′ , rd ′ , rs2 ′ .
C.SUBW is an RV64C/RV128C-only instruction that subtracts the value in register rs2 ′ from thevalue in register rd ′ , then sign-extends the lower 32 bits of the difference before writing the result
to register rd ′ . C.SUBW expands into subw rd ′ , rd ′ , rs2 ′ .
This group of six instructions do not provide large savings individually, but do not occupy much
encoding space and are straightforward to implement, and as a group provide a worthwhile improvement in static and dynamic compression.

Defined Illegal Instruction
15

13

0
3
0

12

0
1
0

11

7 6

0
5
0

2 1

0
5
0

0

0
2
0

A 16-bit instruction with all bits zero is permanently reserved as an illegal instruction.
We reserve all-zero instructions to be illegal instructions to help trap attempts to execute zero-ed
or non-existent portions of the memory space. The all-zero value should not be redefined in any
non-standard extension. Similarly, we reserve instructions with all bits set to 1 (corresponding

110

Volume I: RISC-V Unprivileged ISA V20191213
to very long instructions in the RISC-V variable-length encoding scheme) as illegal to capture
another common value seen in non-existent memory regions.

NOP Instruction
15

13

funct3
3
C.NOP

12

11

imm[5]
1
0

7 6

rd/rs15
0

2 1

imm[4:0]
5
0

0

op
2
C1

C.NOP is a CI-format instruction that does not change any user-visible state, except for advancing
the pc and incrementing any applicable performance counters. C.NOP expands to nop. C.NOP isonly valid when imm=0; the code points with imm̸=0 encode HINTs.

Breakpoint Instruction
15

12 11

funct4
4
C.EBREAK

2 1

0
10
0

0

op
2
C2

Debuggers can use the C.EBREAK instruction, which expands to ebreak, to cause control to betransferred back to the debugging environment. C.EBREAK shares the opcode with the C.ADD
instruction, but with rd and rs2 both zero, thus can also use the CR format.

16.6

Usage of C Instructions in LR/SC Sequences

On implementations that support the C extension, compressed forms of the I instructions permitted inside constrained LR/SC sequences, as described in Section 8.3, are also permitted inside
constrained LR/SC sequences.
The implication is that any implementation that claims to support both the A and C extensions
must ensure that LR/SC sequences containing valid C instructions will eventually complete.

16.7

HINT Instructions

A portion of the RVC encoding space is reserved for microarchitectural HINTs. Like the HINTs
in the RV32I base ISA (see Section 2.9), these instructions do not modify any architectural state,
except for advancing the pc and any applicable performance counters. HINTs are executed as
no-ops on implementations that ignore them.
RVC HINTs are encoded as computational instructions that do not modify the architectural state,either because rd=x0 (e.g. C.ADD x0, t0), or because rd is overwritten with a copy of itself (e.g.
C.ADDI t0, 0).

Volume I: RISC-V Unprivileged ISA V20191213

111

This HINT encoding has been chosen so that simple implementations can ignore HINTs altogether, and instead execute a HINT as a regular computational instruction that happens not tomutate the architectural state.

RVC HINTs do not necessarily expand to their RVI HINT counterparts. For example, C.ADD x0, t0
might not encode the same HINT as ADD x0, x0, t0.
The primary reason to not require an RVC HINT to expand to an RVI HINT is that HINTs
are unlikely to be compressible in the same manner as the underlying computational instruction.
Also, decoupling the RVC and RVI HINT mappings allows the scarce RVC HINT space to beallocated to the most popular HINTs, and in particular, to HINTs that are amenable to macro-op
fusion.

Table 16.3 lists all RVC HINT code points. For RV32C, 78% of the HINT space is reserved forstandard HINTs, but none are presently defined. The remainder of the HINT space is reserved forcustom HINTs: no standard HINTs will ever be defined in this subspace.
Instruction
C.NOP
C.ADDI
C.LI
C.LUI
C.MV
C.ADD

Constraints
nzimm̸=0rd̸=x0, nzimm=0
rd=x0
rd=x0, nzimm̸=0
rd=x0, rs2̸=x0
rd=x0, rs2̸=x0

C.SLLI

rd=x0, nzimm̸=0C.SLLI64
C.SLLI64
C.SRLI64
C.SRAI64

rd=x0
rd̸=x0, RV32 and RV64 only
RV32 and RV64 only
RV32 and RV64 only

Code Points
63
31
64
63
31
31
31 (RV32)
63 (RV64/128)
1
31
8
8

PurposeReserved for future standard use

Reserved for custom use

Table 16.3: RVC HINT instructions.

112

16.8

Volume I: RISC-V Unprivileged ISA V20191213

RVC Instruction Set Listings

Table 16.4 shows a map of the major opcodes for RVC. Each row of the table corresponds to one
quadrant of the encoding space. The last quadrant, which has the two least-significant bits set,corresponds to instructions wider than 16 bits, including those in the base ISAs. Several instructions
are only valid for certain operands; when invalid, they are marked either RES to indicate that the
opcode is reserved for future standard extensions; NSE to indicate that the opcode is reserved forcustom extensions; or HINT to indicate that the opcode is reserved for microarchitectural hints(see Section 16.7).
inst[15:13]
inst[1:0]000

00 ADDI4SPN

01

ADDI

10

SLLI

11

001

010

011

100

101

110

111

FLD
FLW
FSD
FSW
RV32
FLD
LW
LD
Reserved
FSD
SW
SD
RV64
LQ
LD
SQ
SD
RV128
JAL
RV32
ADDIW
LI
LUI/ADDI16SPMISC-ALUJ
BEQZ BNEZ RV64
ADDIW
RV128
FLDSP
FLWSP
FSDSP
FSWSP RV32
FLDSP LWSPLDSP
J[AL]R/MV/ADD FSDSP SWSP SDSP RV64
LQSP
LDSP
SQSP
SDSP RV128>16b

Table 16.4: RVC opcode map
Tables 16.5–16.7 list the RVC instructions.
15 14 13 12

000
000
001
001
010
011
011
100
101
101
110
111
111

11 10

9

8

7

6

5

0
nzuimm[5:4|9:6|2|3]
uimm[5:3]
rs1 ′
uimm[7:6]
uimm[5:4|8]
rs1 ′
uimm[7:6]′
uimm[5:3]
rs1
uimm[2|6]
uimm[5:3]
rs1 ′
uimm[2|6]
uimm[5:3]
rs1 ′
uimm[7:6]—
uimm[5:3]
rs1 ′
uimm[7:6]
uimm[5:4|8]
rs1 ′
uimm[7:6]
uimm[5:3]
rs1 ′
uimm[2|6]′
uimm[5:3]
rs1
uimm[2|6]
uimm[5:3]
rs1 ′
uimm[7:6]

4

3

0
rd ′
rd ′
rd ′
rd ′
rd ′
rd ′
rs2 ′
rs2 ′
rs2 ′
rs2 ′
rs2 ′

2

1

0

00
00
00
00
00
00
00
00
00
00
00
00
00

Illegal instruction
C.ADDI4SPN (RES, nzuimm=0)
C.FLD (RV32/64)
C.LQ (RV128)
C.LWC.FLW (RV32)
C.LD (RV64/128)
Reserved
C.FSD (RV32/64)
C.SQ (RV128)
C.SW
C.FSW (RV32)
C.SD (RV64/128)

Table 16.5: Instruction listing for RVC, Quadrant 0.

Volume I: RISC-V Unprivileged ISA V20191213

15 14 13

12

000
000
001
001
010
011
011
100
100
100
100
100
100
100
100
100
100
100
100
100
101
110
111

nzimm[5]nzimm[5]11 10 9

8

7

6

113

5

4

3

2

1

0
nzimm[4:0]rs1/rd̸=0nzimm[4:0]
imm[11|4|9:8|10|6|7|3:1|5]
imm[5]
rs1/rd̸=0
imm[4:0]
imm[5]
rd̸=0
imm[4:0]nzimm[9]2nzimm[4|6|8:7|5]
nzimm[17]rd̸={0, 2}
nzimm[16:12]′′
nzuimm[5]00
rs1 /rdnzuimm[4:0]000
rs1 ′ /rd ′0nzuimm[5]01
rs1 ′ /rd ′nzuimm[4:0]001
rs1 ′ /rd ′0
imm[5]
10
rs1 ′ /rd ′imm[4:0]0
11
rs1 ′ /rd ′
00
rs2 ′
′
′
0
11
rs1 /rd
01
rs2 ′
′
′
0
11
rs1 /rd
10
rs2 ′
′
′
0
11
rs1 /rd
11
rs2 ′
′
′
1
11
rs1 /rd
00
rs2 ′
1
11
rs1 ′ /rd ′
01
rs2 ′
1
11
—
10
—
1
11
—
11
—
imm[11|4|9:8|10|6|7|3:1|5]
imm[8|4:3]
rs1 ′
imm[7:6|2:1|5]′
imm[8|4:3]
rs1
imm[7:6|2:1|5]

0

01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01

C.NOP (HINT, nzimm̸=0)C.ADDI (HINT, nzimm=0)C.JAL (RV32)
C.ADDIW (RV64/128; RES, rd=0)
C.LI (HINT, rd=0)
C.ADDI16SP (RES, nzimm=0)
C.LUI (RES, nzimm=0; HINT, rd=0)
C.SRLI (RV32 NSE, nzuimm[5]=1)
C.SRLI64 (RV128; RV32/64 HINT)C.SRAI (RV32 NSE, nzuimm[5]=1)
C.SRAI64 (RV128; RV32/64 HINT)
C.ANDI
C.SUB
C.XOR
C.OR
C.AND
C.SUBW (RV64/128; RV32 RES)
C.ADDW (RV64/128; RV32 RES)
Reserved
Reserved
C.J
C.BEQZ
C.BNEZ

Table 16.6: Instruction listing for RVC, Quadrant 1.

15 14 13

000
000
001
001
010
011
011
100
100
100
100
100
101
101
110
111
111

12

11 10 98nzuimm[5]rs1/rd̸=00
rs1/rd̸=0uimm[5]rduimm[5]rd̸=0uimm[5]rd̸=0uimm[5]rduimm[5]rd̸=00
rs1̸=0
0
rd̸=0
1
0
1
rs1̸=01
rs1/rd̸=0uimm[5:3|8:6]
uimm[5:4|9:6]
uimm[5:2|7:6]
uimm[5:2|7:6]
uimm[5:3|8:6]

7

6

5

4

3

nzuimm[4:0]0uimm[4:3|8:6]
uimm[4|9:6]
uimm[4:2|7:6]
uimm[4:2|7:6]
uimm[4:3|8:6]0
rs2̸=000
rs2̸=0
rs2
rs2
rs2
rs2
rs2

2

1

0

10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10

C.SLLI (HINT, rd=0; RV32 NSE, nzuimm[5]=1)
C.SLLI64 (RV128; RV32/64 HINT; HINT, rd=0)
C.FLDSP (RV32/64)
C.LQSP (RV128; RES, rd=0)
C.LWSP (RES, rd=0)
C.FLWSP (RV32)
C.LDSP (RV64/128; RES, rd=0)
C.JR (RES, rs1=0)
C.MV (HINT, rd=0)
C.EBREAK
C.JALR
C.ADD (HINT, rd=0)
C.FSDSP (RV32/64)
C.SQSP (RV128)
C.SWSP
C.FSWSP (RV32)
C.SDSP (RV64/128)

Table 16.7: Instruction listing for RVC, Quadrant 2.

114

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 17“B” Standard Extension for Bit
Manipulation, Version 0.0
This chapter is a placeholder for a future standard extension to provide bit manipulation instructions, including instructions to insert, extract, and test bit fields, and for rotations, funnel shifts,
and bit and byte permutations.
Although bit manipulation instructions are very effective in some application domains, particularly when dealing with externally packed data structures, we excluded them from the base ISA
as they are not useful in all domains and can add additional complexity or instruction formats
to supply all needed operands.
We anticipate the B extension will be a brownfield encoding within the base 30-bit instruction
space.

115

116

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 18“J” Standard Extension for
Dynamically Translated Languages,
Version 0.0
This chapter is a placeholder for a future standard extension to support dynamically translated
languages.
Many popular languages are usually implemented via dynamic translation, including Java andJavascript. These languages can benefit from additional ISA support for dynamic checks andgarbage collection.

117

118

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 19“T” Standard Extension forTransactional Memory, Version 0.0
This chapter is a placeholder for a future standard extension to provide transactional memory
operations.
Despite much research over the last twenty years, and initial commercial implementations, there
is still much debate on the best way to support atomic operations involving multiple addresses.
Our current thoughts are to include a small limited-capacity transactional memory bufferalong the lines of the original transactional memory proposals.

119

120

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 20“P” Standard Extension for
Packed-SIMD Instructions, Version
0.2
Discussions at the 5th RISC-V workshop indicated a desire to drop this packed-SIMD proposal
for floating-point registers in favor of standardizing on the V extension for large floating-point
SIMD operations. However, there was interest in packed-SIMD fixed-point operations for use in
the integer registers of small RISC-V implementations. A task group is working to define the
new P extension.

121

122

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 21“V” Standard Extension for Vector
Operations, Version 0.7
The current working group draft is hosted at https://github.com/riscv/riscv-v-spec.
The base vector extension is intended to provide general support for data-parallel execution within
the 32-bit instruction encoding space, with later vector extensions supporting richer functionality
for certain domains.

123

124

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 22“Zam” Standard Extension for
Misaligned Atomics, v0.1
This chapter defines the “Zam” extension, which extends the “A” extension by standardizing
support for misaligned atomic memory operations (AMOs). On platforms implementing “Zam”,
misaligned AMOs need only execute atomically with respect to other accesses (including non-atomic
loads and stores) to the same address and of the same size. More precisely, execution environments
implementing “Zam” are subject to the following axiom:
Atomicity Axiom for misaligned atomics If r and w are paired misaligned load and store
instructions from a hart h with the same address and of the same size, then there can be no store
instruction s from a hart other than h with the same address and of the same size as r and w suchthat a store operation generated by s lies in between memory operations generated by r and w in
the global memory order. Furthermore, there can be no load instruction l from a hart other thanh with the same address and of the same size as r and w such that a load operation generated byl lies between two memory operations generated by r or by w in the global memory order.
This restricted form of atomicity is intended to balance the needs of applications which require support for misaligned atomics and the ability of the implementation to actually provide the necessary
degree of atomicity.
Aligned instructions under “Zam” continue to behave as they normally do under RVWMO.
The intention of “Zam” is that it can be implemented in one of two ways:
1. On hardware that natively supports atomic misaligned accesses to the address and size inquestion (e.g., for misaligned accesses within a single cache line): by simply following thesame rules that would be applied for aligned AMOs.
2. On hardware that does not natively support misaligned accesses to the address and size inquestion: by trapping on all instructions (including loads) with that address and size andexecuting them (via any number of memory operations) inside a mutex that is a function of
the given memory address and access size. AMOs may be emulated by splitting them into
separate load and store operations, but all preserved program order rules (e.g., incoming
and outgoing syntactic dependencies) must behave as if the AMO is still a single memory
operation.

125

126

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 23“Ztso” Standard Extension for Total
Store Ordering, v0.1
This chapter defines the “Ztso” extension for the RISC-V Total Store Ordering (RVTSO) memory
consistency model. RVTSO is defined as a delta from RVWMO, which is defined in Chapter 14.1.
The Ztso extension is meant to facilitate the porting of code originally written for the x86 or
SPARC architectures, both of which use TSO by default. It also supports implementations which
inherently provide RVTSO behavior and want to expose that fact to software.

RVTSO makes the following adjustments to RVWMO:• All load operations behave as if they have an acquire-RCpc annotation• All store operations behave as if they have a release-RCpc annotation.
• All AMOs behave as if they have both acquire-RCsc and release-RCsc annotations.

These rules render all PPO rules except 4–7 redundant. They also make redundant any non-I/O
fences that do not have both PW and SR set. Finally, they also imply that no memory operation
will be reordered past an AMO in either direction.
In the context of RVTSO, as is the case for RVWMO, the storage ordering annotations areconcisely and completely defined by PPO rules 5–7. In both of these memory models, it is the
Load Value Axiom that allows a hart to forward a value from its store buffer to a subsequent (inprogram order) load—that is to say that stores can be forwarded locally before they are visible toother harts.

In spite of the fact that Ztso adds no new instructions to the ISA, code written assuming RVTSO
will not run correctly on implementations not supporting Ztso. Binaries compiled to run only underZtso should indicate as such via a flag in the binary, so that platforms which do not implement
Ztso can simply refuse to run them.

127

128

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 24

RV32/64G Instruction Set Listings
One goal of the RISC-V project is that it be used as a stable software development target. For
this purpose, we define a combination of a base ISA (RV32I or RV64I) plus selected standard
extensions (IMAFD, Zicsr, Zifencei) as a “general-purpose” ISA, and we use the abbreviation G for
the IMAFDZicsr Zifencei combination of instruction-set extensions. This chapter presents opcode
maps and instruction-set listings for RV32G and RV64G.
inst[4:2]
000
001
010
011
100
101
110
111
inst[6:5](> 32b)00
LOAD
LOAD-FP custom-0 MISC-MEM OP-IMM AUIPC
OP-IMM-32
48b
01 STORE STORE-FP custom-1
AMO
OP
LUI
OP-32
64b
10
MADD
MSUB
NMSUB
NMADD
OP-FP reserved custom-2/rv128
48b
11 BRANCH
JALR
reservedJAL
SYSTEM reserved custom-3/rv128≥ 80b

Table 24.1: RISC-V base opcode map, inst[1:0]=11
Table 24.1 shows a map of the major opcodes for RVG. Major opcodes with 3 or more lower bits
set are reserved for instruction lengths greater than 32 bits. Opcodes marked as reserved should be
avoided for custom instruction-set extensions as they might be used by future standard extensions.
Major opcodes marked as custom-0 and custom-1 will be avoided by future standard extensions andare recommended for use by custom instruction-set extensions within the base 32-bit instruction
format. The opcodes marked custom-2/rv128 and custom-3/rv128 are reserved for future use by
RV128, but will otherwise be avoided for standard extensions and so can also be used for custom
instruction-set extensions in RV32 and RV64.
We believe RV32G and RV64G provide simple but complete instruction sets for a broad range ofgeneral-purpose computing. The optional compressed instruction set described in Chapter 16 canbe added (forming RV32GC and RV64GC) to improve performance, code size, and energy efficiency,
though with some additional hardware complexity.
As we move beyond IMAFDC into further instruction-set extensions, the added instructions tend
to be more domain-specific and only provide benefits to a restricted class of applications, e.g., formultimedia or security. Unlike most commercial ISAs, the RISC-V ISA design clearly separates
the base ISA and broadly applicable standard extensions from these more specialized additions.
Chapter 26 has a more extensive discussion of ways to add extensions to the RISC-V ISA.
129

130

Volume I: RISC-V Unprivileged ISA V20191213

31

27

26 25 24

funct7
imm[11:0]
imm[11:5]
imm[12|10:5]

20

19

rs2

15

14

12

funct3funct3funct3funct3

11

7

6

0

rd
rd
imm[4:0]
imm[4:1|11]
rdrd

opcodeopcodeopcodeopcodeopcodeopcodeR-typeI-typeS-typeB-typeU-typeJ-typeRV32I Base Instruction Set
imm[31:12]
rd
imm[31:12]
rd
imm[20|10:1|11|19:12]
rd
imm[11:0]
rs1
000
rd
imm[12|10:5]
rs2
rs1
000
imm[4:1|11]
imm[12|10:5]
rs2
rs1
001
imm[4:1|11]
imm[12|10:5]
rs2
rs1
100
imm[4:1|11]
imm[12|10:5]
rs2
rs1
101
imm[4:1|11]
imm[12|10:5]
rs2
rs1
110
imm[4:1|11]
imm[12|10:5]
rs2
rs1
111
imm[4:1|11]
imm[11:0]
rs1
000
rd
imm[11:0]
rs1
001
rd
imm[11:0]
rs1
010
rd
imm[11:0]
rs1
100
rd
imm[11:0]
rs1
101
rd
imm[11:5]
rs2
rs1
000
imm[4:0]
imm[11:5]
rs2
rs1
001
imm[4:0]
imm[11:5]
rs2
rs1
010
imm[4:0]
imm[11:0]
rs1
000
rd
imm[11:0]
rs1
010
rd
imm[11:0]
rs1
011
rd
imm[11:0]
rs1
100
rd
imm[11:0]
rs1
110
rd
imm[11:0]
rs1
111
rd
0000000
shamt
rs1
001
rd
0000000
shamt
rs1
101
rd
0100000
shamt
rs1
101
rd
0000000
rs2
rs1
000
rd
0100000
rs2
rs1
000
rd
0000000
rs2
rs1
001
rd
0000000
rs2
rs1
010
rd
0000000
rs2
rs1
011
rd
0000000
rs2
rs1
100
rd
0000000
rs2
rs1
101
rd
0100000
rs2
rs1
101
rd
0000000
rs2
rs1
110
rd
0000000
rs2
rs1
111
rd
fm
pred
succ
rs1
000
rd
000000000000
00000
000
00000
000000000001
00000
000
00000

0110111001011111011111100111110001111000111100011110001111000111100011000001100000110000011000001100000110100011010001101000110010011001001100100110010011001001100100110010011001001100100110110011011001101100110110011011001101100110110011011001101100110110011000111111100111110011

LUI
AUIPC
JAL
JALR
BEQ
BNE
BLT
BGE
BLTU
BGEU
LB
LH
LW
LBU
LHU
SB
SH
SW
ADDI
SLTI
SLTIU
XORI
ORI
ANDI
SLLI
SRLI
SRAI
ADD
SUB
SLL
SLT
SLTU
XOR
SRL
SRA
OR
AND
FENCE
ECALL
EBREAK

rs2
rs2
imm[31:12]
imm[20|10:1|11|19:12]

rs1
rs1
rs1
rs1

Volume I: RISC-V Unprivileged ISA V20191213

31

27

26 25 24

funct7
imm[11:0]
imm[11:5]

20

19

15

12

7

rd
rd
imm[4:0]6

0

RV64I Base Instruction Set (in addition to RV32I)
imm[11:0]
rs1
110
rd
imm[11:0]
rs1
011
rd
imm[11:5]
rs2
rs1
011
imm[4:0]000000
shamt
rs1
001
rd
000000
shamt
rs1
101
rd
010000
shamt
rs1
101
rd
imm[11:0]
rs1
000
rd
0000000
shamt
rs1
001
rd
0000000
shamt
rs1
101
rd
0100000
shamt
rs1
101
rd
0000000
rs2
rs1
000
rd
0100000
rs2
rs1
000
rd
0000000
rs2
rs1
001
rd
0000000
rs2
rs1
101
rd
0100000
rs2
rs1
101
rd

000001100000110100011001001100100110010011001101100110110011011001101101110110111011011101101110110111011

LWU
LD
SD
SLLI
SRLI
SRAI
ADDIW
SLLIW
SRLIW
SRAIW
ADDW
SUBW
SLLW
SRLW
SRAW

RV32/RV64 Zifencei Standard Extension
imm[11:0]
rs1
001
rd

0001111

FENCE.I

RV32/RV64 Zicsr Standard Extension
rs1
001
rd
rs1
010
rd
rs1
011
rd
uimm
101
rd
uimm
110
rd
uimm
111
rd

111001111100111110011111001111100111110011

CSRRW
CSRRS
CSRRC
CSRRWICSRRSICSRRCI

RV32M Standard Extension
rs2
rs1
000
rs2
rs1
001
rs2
rs1
010
rs2
rs1
011
rs2
rs1
100
rs2
rs1
101
rs2
rs1
110
rs2
rs1
111

01100110110011011001101100110110011011001101100110110011

MUL
MULH
MULHSU
MULHU
DIV
DIVU
REM
REMU

RV64M Standard Extension (in addition to RV32M)
0000001
rs2
rs1
000
rd
01110110000001
rs2
rs1
100
rd
01110110000001
rs2
rs1
101
rd
01110110000001
rs2
rs1
110
rd
01110110000001
rs2
rs1
111
rd
0111011

MULW
DIVW
DIVUW
REMW
REMUW

0000001
0000001
0000001
0000001
0000001
0000001
0000001
0000001

funct3funct3funct311

R-typeI-typeS-type

rs2

rs1
rs1
rs1

14

opcodeopcodeopcode

csr
csr
csr
csr
csr
csr

rs2

131

rd
rd
rd
rd
rd
rd
rd
rd

132

Volume I: RISC-V Unprivileged ISA V20191213

31

27

26

25

funct7

00010
00011
00001
00000
00100
01100
01000
10000
10100
11000
11100

00010
00011
00001
00000
00100
01100
01000
10000
10100
11000
11100

24

20

rs2

aq
aq
aq
aq
aq
aq
aq
aq
aq
aq
aq

rl
rl
rl
rl
rl
rl
rl
rl
rl
rl
rl

19

15

rs1

14

12

11

7

6

0

funct3rd

opcodeR-typeRV32A Standard Extension
00000
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010
rs2
rs1
010

rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd

01011110101111010111101011110101111010111101011110101111010111101011110101111LR.W
SC.W
AMOSWAP.W
AMOADD.W
AMOXOR.W
AMOAND.W
AMOOR.W
AMOMIN.W
AMOMAX.W
AMOMINU.W
AMOMAXU.W

01011110101111010111101011110101111010111101011110101111010111101011110101111

LR.D
SC.D
AMOSWAP.DAMOADD.D
AMOXOR.D
AMOAND.D
AMOOR.DAMOMIN.D
AMOMAX.DAMOMINU.D
AMOMAXU.D

RV64A Standard Extension (in addition to RV32A)
aq rl
00000
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd
aq rl
rs2
rs1
011
rd

Volume I: RISC-V Unprivileged ISA V20191213

31

27

26 25

funct7rs3
funct2
imm[11:0]
imm[11:5]

imm[11:0]
imm[11:5]
rs3
00
rs3
00
rs3
00
rs3
00
0000000
0000100
0001000
0001100
0101100
0010000
0010000
0010000
0010100
0010100
1100000
1100000
1110000
1010000
1010000
1010000
1110000
1101000
1101000
1111000

24

20

rs2
rs2

19

15

14

12

11

7

6

0

funct3funct3funct3funct3rdrd
rd
imm[4:0]

opcodeopcodeopcodeopcodeR-typeR4-typeI-typeS-type

RV32F Standard Extension
rs1
010
rs2
rs1
010
rs2
rs1
rm
rs2
rs1
rm
rs2
rs1
rm
rs2
rs1
rm
rs2
rs1
rm
rs2
rs1
rm
rs2
rs1
rm
rs2
rs1
rm
00000
rs1
rm
rs2
rs1
000
rs2
rs1
001
rs2
rs1
010
rs2
rs1
000
rs2
rs1
001
00000
rs1
rm
00001
rs1
rm
00000
rs1
000
rs2
rs1
010
rs2
rs1
001
rs2
rs1
000
00000
rs1
001
00000
rs1
rm
00001
rs1
rm
00000
rs1
000

rd
imm[4:0]
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd
rd

00001110100111
100001110001111001011100111110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011FLWFSW
FMADD.SFMSUB.SFNMSUB.S
FNMADD.S
FADD.S
FSUB.S
FMUL.S
FDIV.SFSQRT.SFSGNJ.SFSGNJN.S
FSGNJX.S
FMIN.S
FMAX.S
FCVT.W.S
FCVT.WU.S
FMV.X.W
FEQ.S
FLT.S
FLE.S
FCLASS.S
FCVT.S.W
FCVT.S.WU
FMV.W.X

1010011101001110100111010011

FCVT.L.S
FCVT.LU.S
FCVT.S.LFCVT.S.LU

rs2

rs1
rs1
rs1
rs1

133

RV64F Standard Extension (in addition to RV32F)
1100000
00010
rs1
rm
rd
1100000
00011
rs1
rm
rd
1101000
00010
rs1
rm
rd
1101000
00011
rs1
rm
rd

134

Volume I: RISC-V Unprivileged ISA V20191213

31

27

26 25

funct7rs3
funct2
imm[11:0]
imm[11:5]

imm[11:0]
imm[11:5]
rs3
01
rs3
01
rs3
01
rs3
01
0000001
0000101
0001001
0001101
0101101
0010001
0010001
0010001
0010101
0010101
0100000
0100001
1010001
1010001
1010001
1110001
1100001
1100001
1101001
1101001

24

20

rs2
rs2

19

15

14

12

funct3funct3funct3funct3

11

7

6

0

rd
rd
rd
imm[4:0]

opcodeopcodeopcodeopcodeR-typeR4-typeI-typeS-type

RV32D Standard Extension
rs1
011
rd
rs2
rs1
011
imm[4:0]
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
00000
rs1
rm
rd
rs2
rs1
000
rd
rs2
rs1
001
rd
rs2
rs1
010
rd
rs2
rs1
000
rd
rs2
rs1
001
rd
00001
rs1
rm
rd
00000
rs1
rm
rd
rs2
rs1
010
rd
rs2
rs1
001
rd
rs2
rs1
000
rd
00000
rs1
001
rd
00000
rs1
rm
rd
00001
rs1
rm
rd
00000
rs1
rm
rd
00001
rs1
rm
rd

00001110100111
100001110001111001011100111110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011FLD
FSD
FMADD.D
FMSUB.DFNMSUB.D
FNMADD.D
FADD.D
FSUB.D
FMUL.D
FDIV.DFSQRT.DFSGNJ.DFSGNJN.D
FSGNJX.D
FMIN.D
FMAX.D
FCVT.S.D
FCVT.D.S
FEQ.D
FLT.D
FLE.D
FCLASS.D
FCVT.W.D
FCVT.WU.D
FCVT.D.W
FCVT.D.WU

101001110100111010011101001110100111010011

FCVT.L.D
FCVT.LU.D
FMV.X.D
FCVT.D.L
FCVT.D.LU
FMV.D.X

rs2

rs1
rs1
rs1
rs1

RV64D Standard Extension (in addition to RV32D)
1100001
00010
rs1
rm
rd
1100001
00011
rs1
rm
rd
1110001
00000
rs1
000
rd
1101001
00010
rs1
rm
rd
1101001
00011
rs1
rm
rd
1111001
00000
rs1
000
rd

Volume I: RISC-V Unprivileged ISA V20191213

31

27

26 25

funct7rs3
funct2
imm[11:0]
imm[11:5]

imm[11:0]
imm[11:5]
rs3
11
rs3
11
rs3
11
rs3
11
00000110000111000101100011110101111001001100100110010011001011100101110100000
01000110100001
010001110100111010011101001111100111100011110001111010111101011

24

20

rs2
rs2

19

15

14

12

funct3funct3funct3funct3

11

7

6

0

rd
rd
rd
imm[4:0]

opcodeopcodeopcodeopcodeR-typeR4-typeI-typeS-typeRV32Q Standard Extension
rs1
100
rd
rs2
rs1
100
imm[4:0]
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
rs2
rs1
rm
rd
00000
rs1
rm
rd
rs2
rs1
000
rd
rs2
rs1
001
rd
rs2
rs1
010
rd
rs2
rs1
000
rd
rs2
rs1
001
rd
00011
rs1
rm
rd
00000
rs1
rm
rd
00011
rs1
rm
rd
00001
rs1
rm
rd
rs2
rs1
010
rd
rs2
rs1
001
rd
rs2
rs1
000
rd
00000
rs1
001
rd
00000
rs1
rm
rd
00001
rs1
rm
rd
00000
rs1
rm
rd
00001
rs1
rm
rd

00001110100111
10000111000111100101110011111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011101001110100111010011FLQ
FSQ
FMADD.Q
FMSUB.QFNMSUB.Q
FNMADD.Q
FADD.Q
FSUB.Q
FMUL.Q
FDIV.QFSQRT.Q
FSGNJ.Q
FSGNJN.Q
FSGNJX.Q
FMIN.Q
FMAX.Q
FCVT.S.Q
FCVT.Q.SFCVT.D.Q
FCVT.Q.D
FEQ.Q
FLT.Q
FLE.Q
FCLASS.Q
FCVT.W.Q
FCVT.WU.Q
FCVT.Q.W
FCVT.Q.WU

1010011101001110100111010011

FCVT.L.Q
FCVT.LU.Q
FCVT.Q.LFCVT.Q.LU

rs2

rs1
rs1
rs1
rs1

135

RV64Q Standard Extension (in addition to RV32Q)
1100011
00010
rs1
rm
rd
1100011
00011
rs1
rm
rd
1101011
00010
rs1
rm
rd
1101011
00011
rs1
rm
rd

Table 24.2: Instruction listing for RISC-V

136

Volume I: RISC-V Unprivileged ISA V20191213

Table 24.3 lists the CSRs that have currently been allocated CSR addresses. The timers, counters,
and floating-point CSRs are the only CSRs defined in this specification.
NumberPrivilege

0x001
0x002
0x003

Read/write
Read/write
Read/write

0xC00
0xC01
0xC02
0xC80
0xC81
0xC82

Read-only
Read-only
Read-only
Read-only
Read-only
Read-only

Name
Description
Floating-Point Control and Status Registers
fflagsFloating-Point Accrued Exceptions.
frm
Floating-Point Dynamic Rounding Mode.
fcsr
Floating-Point Control and Status Register (frm + fflags).
Counters and Timers
cycle
Cycle counter for RDCYCLE instruction.
time
Timer for RDTIME instruction.
instretInstructions-retired counter for RDINSTRET instruction.
cyclehUpper 32 bits of cycle, RV32I only.
timeh
Upper 32 bits of time, RV32I only.
instreth Upper 32 bits of instret, RV32I only.

Table 24.3: RISC-V control and status register (CSR) address map.

Chapter 25

RISC-V Assembly Programmer’s
Handbook
This chapter is a placeholder for an assembly programmer’s manual.
Table 25.1 lists the assembler mnemonics for the x and f registers and their role in the first standard
calling convention.

Register
x0
x1
x2
x3
x4
x5
x6–7
x8
x9
x10–11
x12–17x18–27x28–31
f0–7
f8–9
f10–11
f12–17
f18–27
f28–31

ABI Name
zero
ra
sp
gp
tp
t0
t1–2
s0/fp
s1
a0–1
a2–7
s2–11
t3–6
ft0–7
fs0–1
fa0–1
fa2–7
fs2–11
ft8–11

Description
Hard-wired zero
Return address
Stack pointerGlobal pointerThread pointerTemporary/alternate link register
Temporaries
Saved register/frame pointerSaved register
Function arguments/return values
Function arguments
Saved registers
Temporaries
FP temporaries
FP saved registers
FP arguments/return values
FP arguments
FP saved registers
FP temporaries

Saver—
CallerCallee——CallerCallerCalleeCalleeCallerCallerCalleeCallerCallerCalleeCallerCallerCalleeCallerTable 25.1: Assembler mnemonics for RISC-V integer and floating-point registers, and their rolein the first standard calling convention.

137

138

Volume I: RISC-V Unprivileged ISA V20191213

There may be future different calling conventions, but note that registers x1, x2, and x5 havespecial meanings encoded in the standard ISA and/or the compressed extension.

Tables 25.2 and 25.3 contain a listing of standard RISC-V pseudoinstructions.

Volume I: RISC-V Unprivileged ISA V20191213

139

pseudoinstruction
la rd, symbol (non-PIC )Base Instruction(s)auipc rd, delta[31 : 12] + delta[11]addi rd, rd, delta[11:0]

Meaning
Load absolute address,
where delta = symbol − pcla rd, symbol (PIC )auipc rd, delta[31 : 12] + delta[11]l{w|d} rd, rd, delta[11:0]

Load absolute address,
where delta = GOT[symbol] − pc

lla rd, symbol

auipc rd, delta[31 : 12] + delta[11]addi rd, rd, delta[11:0]

Load local address,
where delta = symbol − pcl{b|h|w|d} rd, symbol

auipc rd, delta[31 : 12] + delta[11]l{b|h|w|d} rd, delta[11:0](rd)Load globals{b|h|w|d} rd, symbol, rt

auipc rt, delta[31 : 12] + delta[11]s{b|h|w|d} rd, delta[11:0](rt)Store global

fl{w|d} rd, symbol, rt

auipc rt, delta[31 : 12] + delta[11]fl{w|d} rd, delta[11:0](rt)Floating-point load global

fs{w|d} rd, symbol, rt

auipc rt, delta[31 : 12] + delta[11]fs{w|d} rd, delta[11:0](rt)Floating-point store global

The base instructions use pc-relative addressing, so the linker subtracts pc from symbol to get delta. The
linker adds delta[11] to the 20-bit high part, counteracting sign extension of the 12-bit low part.
nop
li rd, immediate
mv rd, rs
not rd, rs
neg rd, rs
negw rd, rs
sext.w rd, rs
seqz rd, rs
snez rd, rs
sltz rd, rs
sgtz rd, rs
fmv.s rd, rs
fabs.s rd, rs
fneg.s rd, rs
fmv.d rd, rs
fabs.d rd, rs
fneg.d rd, rs
beqz rs, offset
bnez rs, offset
blez rs, offset
bgez rs, offset
bltz rs, offset
bgtz rs, offset
bgt rs, rt, offset
ble rs, rt, offset
bgtu rs, rt, offset
bleu rs, rt, offset

addi x0, x0, 0
Myriad sequencesaddi rd, rs, 0xori rd, rs, -1
sub rd, x0, rs
subw rd, x0, rs
addiw rd, rs, 0
sltiu rd, rs, 1
sltu rd, x0, rs
slt rd, rs, x0
slt rd, x0, rs
fsgnj.s rd, rs, rs
fsgnjx.s rd, rs, rs
fsgnjn.s rd, rs, rs
fsgnj.d rd, rs, rs
fsgnjx.d rd, rs, rs
fsgnjn.d rd, rs, rs
beq rs, x0, offset
bne rs, x0, offset
bge x0, rs, offset
bge rs, x0, offset
blt rs, x0, offset
blt x0, rs, offset
blt rt, rs, offset
bge rt, rs, offset
bltu rt, rs, offset
bgeu rt, rs, offset

No operation
Load immediate
Copy register
One’s complement
Two’s complement
Two’s complement word
Sign extend word
Set if = zeroSet if ̸= zeroSet if < zeroSet if > zero
Copy single-precision register
Single-precision absolute value
Single-precision negate
Copy double-precision register
Double-precision absolute value
Double-precision negate
Branch if = zeroBranch if ̸= zeroBranch if ≤ zeroBranch if ≥ zeroBranch if < zeroBranch if > zeroBranch if >Branch if ≤Branch if >, unsigned
Branch if ≤, unsigned

Table 25.2: RISC-V pseudoinstructions.

140

Volume I: RISC-V Unprivileged ISA V20191213

pseudoinstruction
j offset
jal offset
jr rs
jalr rs
ret
call offset
tail offset
fence
rdinstret[h] rdrdcycle[h] rd
rdtime[h] rd
csrr rd, csr
csrw csr, rs
csrs csr, rs
csrc csr, rs
csrwi csr, imm
csrsi csr, imm
csrci csr, imm
frcsr rdfscsr rd, rs
fscsr rs
frrm rdfsrm rd, rs
fsrm rs
frflags rd
fsflags rd, rs
fsflags rs

Base Instruction
jal x0, offset
jal x1, offset
jalr x0, 0(rs)jalr x1, 0(rs)jalr x0, 0(x1)auipc x1, offset[31 : 12] + offset[11]jalr x1, offset[11:0](x1)auipc x6, offset[31 : 12] + offset[11]jalr x0, offset[11:0](x6)fence iorw, iorw
csrrs rd, instret[h], x0
csrrs rd, cycle[h], x0
csrrs rd, time[h], x0
csrrs rd, csr, x0
csrrw x0, csr, rs
csrrs x0, csr, rs
csrrc x0, csr, rs
csrrwi x0, csr, imm
csrrsi x0, csr, imm
csrrci x0, csr, imm
csrrs rd, fcsr, x0
csrrw rd, fcsr, rs
csrrw x0, fcsr, rs
csrrs rd, frm, x0
csrrw rd, frm, rs
csrrw x0, frm, rs
csrrs rd, fflags, x0
csrrw rd, fflags, rs
csrrw x0, fflags, rs

Meaning
Jump
Jump and link
Jump register
Jump and link register
Return from subroutine
Call far-away subroutine
Tail call far-away subroutine
Fence on all memory and I/O
Read instructions-retired counter
Read cycle counter
Read real-time clock
Read CSR
Write CSR
Set bits in CSR
Clear bits in CSR
Write CSR, immediate
Set bits in CSR, immediate
Clear bits in CSR, immediate
Read FP control/status register
Swap FP control/status register
Write FP control/status register
Read FP rounding mode
Swap FP rounding mode
Write FP rounding mode
Read FP exception flags
Swap FP exception flags
Write FP exception flags

Table 25.3: RISC-V pseudoinstructions.

Chapter 26

Extending RISC-V
In addition to supporting standard general-purpose software development, another goal of RISC-V
is to provide a basis for more specialized instruction-set extensions or more customized accelerators.
The instruction encoding spaces and optional variable-length instruction encoding are designed tomake it easier to leverage software development effort for the standard ISA toolchain when building
more customized processors. For example, the intent is to continue to provide full software support
for implementations that only use the standard I base, perhaps together with many non-standard
instruction-set extensions.
This chapter describes various ways in which the base RISC-V ISA can be extended, together withthe scheme for managing instruction-set extensions developed by independent groups. This volume
only deals with the unprivileged ISA, although the same approach and terminology is used forsupervisor-level extensions described in the second volume.

26.1

Extension Terminology

This section defines some standard terminology for describing RISC-V extensions.

Standard versus Non-Standard Extension
Any RISC-V processor implementation must support a base integer ISA (RV32I or RV64I). In
addition, an implementation may support one or more extensions. We divide extensions into two
broad categories: standard versus non-standard.
• A standard extension is one that is generally useful and that is designed to not conflict withany other standard extension. Currently, “MAFDQLCBTPV”, described in other chaptersof this manual, are either complete or planned standard extensions.
• A non-standard extension may be highly specialized and may conflict with other standard
or non-standard extensions. We anticipate a wide variety of non-standard extensions will be
developed over time, with some eventually being promoted to standard extensions.

141

142

Volume I: RISC-V Unprivileged ISA V20191213

Instruction Encoding Spaces and Prefixes
An instruction encoding space is some number of instruction bits within which a base ISA or
ISA extension is encoded. RISC-V supports varying instruction lengths, but even within a single
instruction length, there are various sizes of encoding space available. For example, the base ISA
is defined within a 30-bit encoding space (bits 31–2 of the 32-bit instruction), while the atomic
extension “A” fits within a 25-bit encoding space (bits 31–7).
We use the term prefix to refer to the bits to the right of an instruction encoding space (since
instruction fetch in RISC-V is little-endian, the bits to the right are stored at earlier memory
addresses, hence form a prefix in instruction-fetch order). The prefix for the standard base ISA
encoding is the two-bit “11” field held in bits 1–0 of the 32-bit word, while the prefix for the
standard atomic extension “A” is the seven-bit “0101111” field held in bits 6–0 of the 32-bit word
representing the AMO major opcode. A quirk of the encoding format is that the 3-bit funct3
field used to encode a minor opcode is not contiguous with the major opcode bits in the 32-bit
instruction format, but is considered part of the prefix for 22-bit instruction spaces.
Although an instruction encoding space could be of any size, adopting a smaller set of common
sizes simplifies packing independently developed extensions into a single global encoding. Table 26.1
gives the suggested sizes for RISC-V.
Size

Usage

14-bit22-bit25-bit30-bit32-bit37-bit40-bit45-bit48-bit52-bitQuadrant of compressed 16-bit encoding
Minor opcode in base 32-bit encoding
Major opcode in base 32-bit encoding
Quadrant of base 32-bit encoding
Minor opcode in 48-bit encoding
Major opcode in 48-bit encoding
Quadrant of 48-bit encoding
Sub-minor opcode in 64-bit encoding
Minor opcode in 64-bit encoding
Major opcode in 64-bit encoding# Available in standard instruction length
16-bit 32-bit 48-bit
64-bit
3
28
220
235
32
217
232
12
1
2
227
210
225
32
220
4
217
212
29
32

Table 26.1: Suggested standard RISC-V instruction encoding space sizes.

Greenfield versus Brownfield Extensions
We use the term greenfield extension to describe an extension that begins populating a new instruction encoding space, and hence can only cause encoding conflicts at the prefix level. We
use the term brownfield extension to describe an extension that fits around existing encodings ina previously defined instruction space. A brownfield extension is necessarily tied to a particulargreenfield parent encoding, and there may be multiple brownfield extensions to the same greenfieldparent encoding. For example, the base ISAs are greenfield encodings of a 30-bit instruction space,
while the FDQ floating-point extensions are all brownfield extensions adding to the parent base
ISA 30-bit encoding space.

Volume I: RISC-V Unprivileged ISA V20191213

143

Note that we consider the standard A extension to have a greenfield encoding as it defines a newpreviously empty 25-bit encoding space in the leftmost bits of the full 32-bit base instruction
encoding, even though its standard prefix locates it within the 30-bit encoding space of the base
ISA. Changing only its single 7-bit prefix could move the A extension to a different 30-bit encoding
space while only worrying about conflicts at the prefix level, not within the encoding space itself.

Greenfield
Brownfield

Adds state
RV32I(30), RV64I(30)
F(I), D(F), Q(D)No new state
A(25)
M(I)

Table 26.2: Two-dimensional characterization of standard instruction-set extensions.
Table 26.2 shows the bases and standard extensions placed in a simple two-dimensional taxonomy.
One axis is whether the extension is greenfield or brownfield, while the other axis is whether theextension adds architectural state. For greenfield extensions, the size of the instruction encoding
space is given in parentheses. For brownfield extensions, the name of the extension (greenfield or
brownfield) it builds upon is given in parentheses. Additional user-level architectural state usually
implies changes to the supervisor-level system or possibly to the standard calling convention.
Note that RV64I is not considered an extension of RV32I, but a different complete base encoding.

Standard-Compatible Global Encodings
A complete or global encoding of an ISA for an actual RISC-V implementation must allocate aunique non-conflicting prefix for every included instruction encoding space. The bases and every
standard extension have each had a standard prefix allocated to ensure they can all coexist in a
global encoding.
A standard-compatible global encoding is one where the base and every included standard extension
have their standard prefixes. A standard-compatible global encoding can include non-standard
extensions that do not conflict with the included standard extensions. A standard-compatible
global encoding can also use standard prefixes for non-standard extensions if the associated standard
extensions are not included in the global encoding. In other words, a standard extension must use
its standard prefix if included in a standard-compatible global encoding, but otherwise its prefix isfree to be reallocated. These constraints allow a common toolchain to target the standard subset
of any RISC-V standard-compatible global encoding.

Guaranteed Non-Standard Encoding SpaceTo support development of proprietary custom extensions, portions of the encoding space are
guaranteed to never be used by standard extensions.

144

Volume I: RISC-V Unprivileged ISA V20191213

26.2

RISC-V Extension Design Philosophy

We intend to support a large number of independently developed extensions by encouraging extension developers to operate within instruction encoding spaces, and by providing tools to packthese into a standard-compatible global encoding by allocating unique prefixes. Some extensions
are more naturally implemented as brownfield augmentations of existing extensions, and will sharewhatever prefix is allocated to their parent greenfield extension. The standard extension prefixes
avoid spurious incompatibilities in the encoding of core functionality, while allowing custom packingof more esoteric extensions.
This capability of repacking RISC-V extensions into different standard-compatible global encodings
can be used in a number of ways.
One use-case is developing highly specialized custom accelerators, designed to run kernels fromimportant application domains. These might want to drop all but the base integer ISA and add
in only the extensions that are required for the task in hand. The base ISA has been designed toplace minimal requirements on a hardware implementation, and has been encoded to use only asmall fraction of a 32-bit instruction encoding space.
Another use-case is to build a research prototype for a new type of instruction-set extension. The
researchers might not want to expend the effort to implement a variable-length instruction-fetch
unit, and so would like to prototype their extension using a simple 32-bit fixed-width instruction
encoding. However, this new extension might be too large to coexist with standard extensions in
the 32-bit space. If the research experiments do not need all of the standard extensions, a standardcompatible global encoding might drop the unused standard extensions and reuse their prefixes toplace the proposed extension in a non-standard location to simplify engineering of the research
prototype. Standard tools will still be able to target the base and any standard extensions that arepresent to reduce development time. Once the instruction-set extension has been evaluated andrefined, it could then be made available for packing into a larger variable-length encoding space to
avoid conflicts with all standard extensions.
The following sections describe increasingly sophisticated strategies for developing implementations
with new instruction-set extensions. These are mostly intended for use in highly customized, educational, or experimental architectures rather than for the main line of RISC-V ISA development.

26.3

Extensions within fixed-width 32-bit instruction format

In this section, we discuss adding extensions to implementations that only support the base fixedwidth 32-bit instruction format.
We anticipate the simplest fixed-width 32-bit encoding will be popular for many restricted accelerators and research prototypes.

Volume I: RISC-V Unprivileged ISA V20191213

145

Available 30-bit instruction encoding spaces
In the standard encoding, three of the available 30-bit instruction encoding spaces (those with 2-bit
prefixes 00, 01, and 10) are used to enable the optional compressed instruction extension. However,if the compressed instruction-set extension is not required, then these three further 30-bit encoding
spaces become available. This quadruples the available encoding space within the 32-bit format.

Available 25-bit instruction encoding spaces
A 25-bit instruction encoding space corresponds to a major opcode in the base and standard
extension encodings.
There are four major opcodes expressly reserved for custom extensions (Table 24.1), each of which
represents a 25-bit encoding space. Two of these are reserved for eventual use in the RV128 baseencoding (will be OP-IMM-64 and OP-64), but can be used for standard or non-standard extensions
for RV32 and RV64.
The two opcodes reserved for RV64 (OP-IMM-32 and OP-32) can also be used for standard andnon-standard extensions to RV32 only.
If an implementation does not require floating-point, then the seven major opcodes reserved forstandard floating-point extensions (LOAD-FP, STORE-FP, MADD, MSUB, NMSUB, NMADD,OP-FP) can be reused for non-standard extensions. Similarly, the AMO major opcode can bereused if the standard atomic extensions are not required.
If an implementation does not require instructions longer than 32-bits, then an additional four
major opcodes are available (those marked in gray in Table 24.1).
The base RV32I encoding uses only 11 major opcodes plus 3 reserved opcodes, leaving up to 18
available for extensions. The base RV64I encoding uses only 13 major opcodes plus 3 reserved
opcodes, leaving up to 16 available for extensions.

Available 22-bit instruction encoding spaces
A 22-bit encoding space corresponds to a funct3 minor opcode space in the base and standard
extension encodings. Several major opcodes have a funct3 field minor opcode that is not completely
occupied, leaving available several 22-bit encoding spaces.
Usually a major opcode selects the format used to encode operands in the remaining bits of the
instruction, and ideally, an extension should follow the operand format of the major opcode tosimplify hardware decoding.

Other spaces
Smaller spaces are available under certain major opcodes, and not all minor opcodes are entirely
filled.

146

Volume I: RISC-V Unprivileged ISA V20191213

26.4

Adding aligned 64-bit instruction extensions

The simplest approach to provide space for extensions that are too large for the base 32-bit fixedwidth instruction format is to add naturally aligned 64-bit instructions. The implementation muststill support the 32-bit base instruction format, but can require that 64-bit instructions are aligned
on 64-bit boundaries to simplify instruction fetch, with a 32-bit NOP instruction used as alignment
padding where necessary.
To simplify use of standard tools, the 64-bit instructions should be encoded as described in Figure 1.1. However, an implementation might choose a non-standard instruction-length encoding for
64-bit instructions, while retaining the standard encoding for 32-bit instructions. For example, if
compressed instructions are not required, then a 64-bit instruction could be encoded using one ormore zero bits in the first two bits of an instruction.
We anticipate processor generators that produce instruction-fetch units capable of automaticallyhandling any combination of supported variable-length instruction encodings.

26.5

Supporting VLIW encodings

Although RISC-V was not designed as a base for a pure VLIW machine, VLIW encodings can be
added as extensions using several alternative approaches. In all cases, the base 32-bit encoding has
to be supported to allow use of any standard software tools.

Fixed-size instruction group
The simplest approach is to define a single large naturally aligned instruction format (e.g., 128 bits)
within which VLIW operations are encoded. In a conventional VLIW, this approach would tend
to waste instruction memory to hold NOPs, but a RISC-V-compatible implementation would haveto also support the base 32-bit instructions, confining the VLIW code size expansion to VLIWaccelerated functions.

Encoded-Length Groups
Another approach is to use the standard length encoding from Figure 1.1 to encode parallel instruction groups, allowing NOPs to be compressed out of the VLIW instruction. For example,
a 64-bit instruction could hold two 28-bit operations, while a 96-bit instruction could hold three
28-bit operations, and so on. Alternatively, a 48-bit instruction could hold one 42-bit operation,
while a 96-bit instruction could hold two 42-bit operations, and so on.
This approach has the advantage of retaining the base ISA encoding for instructions holding asingle operation, but has the disadvantage of requiring a new 28-bit or 42-bit encoding for operations
within the VLIW instructions, and misaligned instruction fetch for larger groups. One simplification
is to not allow VLIW instructions to straddle certain microarchitecturally significant boundaries(e.g., cache lines or virtual memory pages).

Volume I: RISC-V Unprivileged ISA V20191213

147

Fixed-Size Instruction Bundles
Another approach, similar to Itanium, is to use a larger naturally aligned fixed instruction bundle
size (e.g., 128 bits) across which parallel operation groups are encoded. This simplifies instruction
fetch, but shifts the complexity to the group execution engine. To remain RISC-V compatible, thebase 32-bit instruction would still have to be supported.

End-of-Group bits in Prefix
None of the above approaches retains the RISC-V encoding for the individual operations within
a VLIW instruction. Yet another approach is to repurpose the two prefix bits in the fixed-width
32-bit encoding. One prefix bit can be used to signal “end-of-group” if set, while the second bit
could indicate execution under a predicate if clear. Standard RISC-V 32-bit instructions generated
by tools unaware of the VLIW extension would have both prefix bits set (11) and thus have thecorrect semantics, with each instruction at the end of a group and not predicated.
The main disadvantage of this approach is that the base ISA lacks the complex predication support
usually required in an aggressive VLIW system, and it is difficult to add space to specify morepredicate registers in the standard 30-bit encoding space.

148

Volume I: RISC-V Unprivileged ISA V20191213

Chapter 27

ISA Extension Naming Conventions
This chapter describes the RISC-V ISA extension naming scheme that is used to concisely describe
the set of instructions present in a hardware implementation, or the set of instructions used by anapplication binary interface (ABI).
The RISC-V ISA is designed to support a wide variety of implementations with various experimental instruction-set extensions. We have found that an organized naming scheme simplifies
software tools and documentation.

27.1

Case Sensitivity

The ISA naming strings are case insensitive.

27.2

Base Integer ISA

RISC-V ISA strings begin with either RV32I, RV32E, RV64I, or RV128I indicating the supported
address space size in bits for the base integer ISA.

27.3

Instruction-Set Extension Names

Standard ISA extensions are given a name consisting of a single letter. For example, the first
four standard extensions to the integer bases are: “M” for integer multiplication and division, “A”
for atomic memory instructions, “F” for single-precision floating-point instructions, and “D” fordouble-precision floating-point instructions. Any RISC-V instruction-set variant can be succinctly
described by concatenating the base integer prefix with the names of the included extensions, e.g.,“RV64IMAFD”.

149

150

Volume I: RISC-V Unprivileged ISA V20191213

We have also defined an abbreviation “G” to represent the “IMAFDZicsr Zifencei” base and extensions, as this is intended to represent our standard general-purpose ISA.
Standard extensions to the RISC-V ISA are given other reserved letters, e.g., “Q” for quad-precision
floating-point, or “C” for the 16-bit compressed instruction format.
Some ISA extensions depend on the presence of other extensions, e.g., “D” depends on “F” and “F”
depends on “Zicsr”. These dependences may be implicit in the ISA name: for example, RV32IF isequivalent to RV32IFZicsr, and RV32ID is equivalent to RV32IFD and RV32IFDZicsr.

27.4

Version Numbers

Recognizing that instruction sets may expand or alter over time, we encode extension version
numbers following the extension name. Version numbers are divided into major and minor version numbers, separated by a “p”. If the minor version is “0”, then “p0” can be omitted fromthe version string. Changes in major version numbers imply a loss of backwards compatibility,
whereas changes in only the minor version number must be backwards-compatible. For example,
the original 64-bit standard ISA defined in release 1.0 of this manual can be written in full as“RV64I1p0M1p0A1p0F1p0D1p0”, more concisely as “RV64I1M1A1F1D1”.
We introduced the version numbering scheme with the second release. Hence, we define the default
version of a standard extension to be the version present at that time, e.g., “RV32I” is equivalent
to “RV32I2”.

27.5

Underscores

Underscores “ ” may be used to separate ISA extensions to improve readability and to provide
disambiguation, e.g., “RV32I2 M2 A2”.
Because the “P” extension for Packed SIMD can be confused for the decimal point in a version
number, it must be preceded by an underscore if it follows a number. For example, “rv32i2p2”
means version 2.2 of RV32I, whereas “rv32i2 p2” means version 2.0 of RV32I with version 2.0 of
the P extension.

27.6

Additional Standard Extension Names

Standard extensions can also be named using a single “Z” followed by an alphabetical name andan optional version number. For example, “Zifencei” names the instruction-fetch fence extension
described in Chapter 3; “Zifencei2” and “Zifencei2p0” name version 2.0 of same.
The first letter following the “Z” conventionally indicates the most closely related alphabeticalextension category, IMAFDQLCBJTPVN. For the “Zam” extension for misaligned atomics, forexample, the letter “a” indicates the extension is related to the “A” standard extension. If multiple

Volume I: RISC-V Unprivileged ISA V20191213

151“Z” extensions are named, they should be ordered first by category, then alphabetically within acategory—for example, “Zicsr Zifencei Zam”.
Extensions with the “Z” prefix must be separated from other multi-letter extensions by an underscore, e.g., “RV32IMACZicsr Zifencei”.

27.7

Supervisor-level Instruction-Set Extensions

Standard supervisor-level instruction-set extensions are defined in Volume II, but are named using“S” as a prefix, followed by an alphabetical name and an optional version number. Supervisor-level
extensions must be separated from other multi-letter extensions by an underscore.
Standard supervisor-level extensions should be listed after standard unprivileged extensions. If
multiple supervisor-level extensions are listed, they should be ordered alphabetically.

27.8

Hypervisor-level Instruction-Set Extensions

Standard hypervisor-level instruction-set extensions are named like supervisor-level extensions, but
beginning with the letter “H” instead of the letter “S”.
Standard hypervisor-level extensions should be listed after standard lesser-privileged extensions. If
multiple hypervisor-level extensions are listed, they should be ordered alphabetically.

27.9

Machine-level Instruction-Set Extensions

Standard machine-level instruction-set extensions are prefixed with the three letters “Zxm”.
Standard machine-level extensions should be listed after standard lesser-privileged extensions. If
multiple machine-level extensions are listed, they should be ordered alphabetically.

27.10

Non-Standard Extension Names

Non-standard extensions are named using a single “X” followed by an alphabetical name and an
optional version number. For example, “Xhwacha” names the Hwacha vector-fetch ISA extension;“Xhwacha2” and “Xhwacha2p0” name version 2.0 of same.
Non-standard extensions must be listed after all standard extensions. They must be separated fromother multi-letter extensions by an underscore. For example, an ISA with non-standard extensions
Argle and Bargle may be named “RV64IZifencei Xargle Xbargle”.
If multiple non-standard extensions are listed, they should be ordered alphabetically.

152

27.11

Volume I: RISC-V Unprivileged ISA V20191213

Subset Naming Convention

Table 27.1 summarizes the standardized extension names.
SubsetName

ImpliesBase ISA
IntegerI
Reduced Integer
E
Standard Unprivileged Extensions
Integer Multiplication and Division
M
AtomicsA
Single-Precision Floating-PointF
Zicsr
Double-Precision Floating-PointD
F
GeneralG
IMADZifencei
Quad-Precision Floating-Point
Q
D
Decimal Floating-PointL
16-bit Compressed Instructions
C
Bit Manipulation
B
Dynamic Languages
J
Transactional Memory
T
Packed-SIMD Extensions
P
Vector Extensions
V
User-Level Interrupts
N
Control and Status Register Access
Zicsr
Instruction-Fetch Fence
Zifencei
Misaligned Atomics
Zam
A
Total Store Ordering
Ztso
Standard Supervisor-Level Extensions
Supervisor-level extension “def”
SdefStandard Hypervisor-Level Extensions
Hypervisor-level extension “ghi”
HghiStandard Machine-Level Extensions
Machine-level extension “jkl”
ZxmjklNon-Standard Extensions
Non-standard extension “mno”
Xmno
Table 27.1: Standard ISA extension names. The table also defines the canonical order in which
extension names must appear in the name string, with top-to-bottom in table indicating first-to-lastin the name string, e.g., RV32IMACV is legal, whereas RV32IMAVC is not.

Chapter 28

History and Acknowledgments
28.1“Why Develop a new ISA?” Rationale from Berkeley GroupWe developed RISC-V to support our own needs in research and education, where our group isparticularly interested in actual hardware implementations of research ideas (we have completed
eleven different silicon fabrications of RISC-V since the first edition of this specification), and inproviding real implementations for students to explore in classes (RISC-V processor RTL designs
have been used in multiple undergraduate and graduate classes at Berkeley). In our current research, we are especially interested in the move towards specialized and heterogeneous accelerators,
driven by the power constraints imposed by the end of conventional transistor scaling. We wanted
a highly flexible and extensible base ISA around which to build our research effort.
A question we have been repeatedly asked is “Why develop a new ISA?” The biggest obvious benefit
of using an existing commercial ISA is the large and widely supported software ecosystem, bothdevelopment tools and ported applications, which can be leveraged in research and teaching. Other
benefits include the existence of large amounts of documentation and tutorial examples. However,
our experience of using commercial instruction sets for research and teaching is that these benefits
are smaller in practice, and do not outweigh the disadvantages:• Commercial ISAs are proprietary. Except for SPARC V8, which is an open IEEE
standard [2], most owners of commercial ISAs carefully guard their intellectual property anddo not welcome freely available competitive implementations. This is much less of an issue
for academic research and teaching using only software simulators, but has been a major
concern for groups wishing to share actual RTL implementations. It is also a major concern
for entities who do not want to trust the few sources of commercial ISA implementations,but who are prohibited from creating their own clean room implementations. We cannot
guarantee that all RISC-V implementations will be free of third-party patent infringements,
but we can guarantee we will not attempt to sue a RISC-V implementor.
• Commercial ISAs are only popular in certain market domains. The most obvious
examples at time of writing are that the ARM architecture is not well supported in the server
space, and the Intel x86 architecture (or for that matter, almost every other architecture)
is not well supported in the mobile space, though both Intel and ARM are attempting to
153

154

Volume I: RISC-V Unprivileged ISA V20191213
enter each other’s market segments. Another example is ARC and Tensilica, which provide
extensible cores but are focused on the embedded space. This market segmentation dilutes
the benefit of supporting a particular commercial ISA as in practice the software ecosystem
only exists for certain domains, and has to be built for others.
• Commercial ISAs come and go. Previous research infrastructures have been built aroundcommercial ISAs that are no longer popular (SPARC, MIPS) or even no longer in production(Alpha). These lose the benefit of an active software ecosystem, and the lingering intellectual
property issues around the ISA and supporting tools interfere with the ability of interested
third parties to continue supporting the ISA. An open ISA might also lose popularity, but
any interested party can continue using and developing the ecosystem.
• Popular commercial ISAs are complex. The dominant commercial ISAs (x86 and ARM)
are both very complex to implement in hardware to the level of supporting common software
stacks and operating systems. Worse, nearly all the complexity is due to bad, or at least
outdated, ISA design decisions rather than features that truly improve efficiency.
• Commercial ISAs alone are not enough to bring up applications. Even if we expend
the effort to implement a commercial ISA, this is not enough to run existing applications forthat ISA. Most applications need a complete ABI (application binary interface) to run, notjust the user-level ISA. Most ABIs rely on libraries, which in turn rely on operating system
support. To run an existing operating system requires implementing the supervisor-level ISA
and device interfaces expected by the OS. These are usually much less well-specified andconsiderably more complex to implement than the user-level ISA.
• Popular commercial ISAs were not designed for extensibility. The dominant commercial ISAs were not particularly designed for extensibility, and as a consequence have added
considerable instruction encoding complexity as their instruction sets have grown. Companies
such as Tensilica (acquired by Cadence) and ARC (acquired by Synopsys) have built ISAs
and toolchains around extensibility, but have focused on embedded applications rather than
general-purpose computing systems.
• A modified commercial ISA is a new ISA. One of our main goals is to support architecture research, including major ISA extensions. Even small extensions diminish the benefit
of using a standard ISA, as compilers have to be modified and applications rebuilt fromsource code to use the extension. Larger extensions that introduce new architectural statealso require modifications to the operating system. Ultimately, the modified commercial ISA
becomes a new ISA, but carries along all the legacy baggage of the base ISA.

Our position is that the ISA is perhaps the most important interface in a computing system, andthere is no reason that such an important interface should be proprietary. The dominant commercial
ISAs are based on instruction-set concepts that were already well known over 30 years ago. Softwaredevelopers should be able to target an open standard hardware target, and commercial processor
designers should compete on implementation quality.
We are far from the first to contemplate an open ISA design suitable for hardware implementation.
We also considered other existing open ISA designs, of which the closest to our goals was the
OpenRISC architecture [12]. We decided against adopting the OpenRISC ISA for several technicalreasons:

Volume I: RISC-V Unprivileged ISA V20191213

155• OpenRISC has condition codes and branch delay slots, which complicate higher performance
implementations.
• OpenRISC uses a fixed 32-bit encoding and 16-bit immediates, which precludes a denser
instruction encoding and limits space for later expansion of the ISA.
• OpenRISC does not support the 2008 revision to the IEEE 754 floating-point standard.
• The OpenRISC 64-bit design had not been completed when we began.
By starting from a clean slate, we could design an ISA that met all of our goals, though of course,
this took far more effort than we had planned at the outset. We have now invested considerable
effort in building up the RISC-V ISA infrastructure, including documentation, compiler tool chains,
operating system ports, reference ISA simulators, FPGA implementations, efficient ASIC implementations, architecture test suites, and teaching materials. Since the last edition of this manual,
there has been considerable uptake of the RISC-V ISA in both academia and industry, and wehave created the non-profit RISC-V Foundation to protect and promote the standard. The RISCV Foundation website at https://riscv.org contains the latest information on the Foundation
membership and various open-source projects using RISC-V.

28.2

History from Revision 1.0 of ISA manual

The RISC-V ISA and instruction-set manual builds upon several earlier projects. Several aspects ofthe supervisor-level machine and the overall format of the manual date back to the T0 (Torrent-0)
vector microprocessor project at UC Berkeley and ICSI, begun in 1992. T0 was a vector processor
based on the MIPS-II ISA, with Krste Asanović as main architect and RTL designer, and Brian
Kingsbury and Bertrand Irrisou as principal VLSI implementors. David Johnson at ICSI was amajor contributor to the T0 ISA design, particularly supervisor mode, and to the manual text.
John Hauser also provided considerable feedback on the T0 ISA design.
The Scale (Software-Controlled Architecture for Low Energy) project at MIT, begun in 2000, built
upon the T0 project infrastructure, refined the supervisor-level interface, and moved away from the
MIPS scalar ISA by dropping the branch delay slot. Ronny Krashinsky and Christopher Batten
were the principal architects of the Scale Vector-Thread processor at MIT, while Mark Hampton
ported the GCC-based compiler infrastructure and tools for Scale.
A lightly edited version of the T0 MIPS scalar processor specification (MIPS-6371) was used inteaching a new version of the MIT 6.371 Introduction to VLSI Systems class in the Fall 2002
semester, with Chris Terman and Krste Asanović as lecturers. Chris Terman contributed mostof the lab material for the class (there was no TA!). The 6.371 class evolved into the trial 6.884
Complex Digital Design class at MIT, taught by Arvind and Krste Asanović in Spring 2005, whichbecame a regular Spring class 6.375. A reduced version of the Scale MIPS-based scalar ISA, named
SMIPS, was used in 6.884/6.375. Christopher Batten was the TA for the early offerings of theseclasses and developed a considerable amount of documentation and lab material based around the
SMIPS ISA. This same SMIPS lab material was adapted and enhanced by TA Yunsup Lee for
the UC Berkeley Fall 2009 CS250 VLSI Systems Design class taught by John Wawrzynek, Krste
Asanović, and John Lazzaro.

156

Volume I: RISC-V Unprivileged ISA V20191213

The Maven (Malleable Array of Vector-thread ENgines) project was a second-generation vectorthread architecture. Its design was led by Christopher Batten when he was an Exchange Scholar
at UC Berkeley starting in summer 2007. Hidetaka Aoki, a visiting industrial fellow from Hitachi,gave considerable feedback on the early Maven ISA and microarchitecture design. The Maven
infrastructure was based on the Scale infrastructure but the Maven ISA moved further away from
the MIPS ISA variant defined in Scale, with a unified floating-point and integer register file. Maven
was designed to support experimentation with alternative data-parallel accelerators. Yunsup Lee
was the main implementor of the various Maven vector units, while Rimas Avižienis was the main
implementor of the various Maven scalar units. Yunsup Lee and Christopher Batten ported GCC
to work with the new Maven ISA. Christopher Celio provided the initial definition of a traditional
vector instruction set (“Flood”) variant of Maven.
Based on experience with all these previous projects, the RISC-V ISA definition was begun in
Summer 2010, with Andrew Waterman, Yunsup Lee, Krste Asanović, and David Patterson as
principal designers. An initial version of the RISC-V 32-bit instruction subset was used in the UC
Berkeley Fall 2010 CS250 VLSI Systems Design class, with Yunsup Lee as TA. RISC-V is a clean
break from the earlier MIPS-inspired designs. John Hauser contributed to the floating-point ISA
definition, including the sign-injection instructions and a register encoding scheme that permitsinternal recoding of floating-point values.

28.3

History from Revision 2.0 of ISA manual

Multiple implementations of RISC-V processors have been completed, including several silicon
fabrications, as shown in Figure 28.1.
Name
Raven-1
EOS14
EOS16
Raven-2
EOS18
EOS20
Raven-3
EOS22

Tapeout Date
May 29, 2011
April 1, 2012
August 17, 2012
August 22, 2012
February 6, 2013
July 3, 2013
September 26, 2013
March 7, 2014

Process
ST 28nm FDSOIIBM 45nm SOI
IBM 45nm SOI
ST 28nm FDSOIIBM 45nm SOI
IBM 45nm SOI
ST 28nm SOI
IBM 45nm SOIISA
RV64G1 Xhwacha1
RV64G1p1 Xhwacha2
RV64G1p1 Xhwacha2
RV64G1p1 Xhwacha2
RV64G1p1 Xhwacha2
RV64G1p99 Xhwacha2
RV64G1p99 Xhwacha2
RV64G1p9999 Xhwacha3

Table 28.1: Fabricated RISC-V testchips.
The first RISC-V processors to be fabricated were written in Verilog and manufactured in a preproduction 28 nm FDSOI technology from ST as the Raven-1 testchip in 2011. Two cores weredeveloped by Yunsup Lee and Andrew Waterman, advised by Krste Asanović, and fabricatedtogether: 1) an RV64 scalar core with error-detecting flip-flops, and 2) an RV64 core with anattached 64-bit floating-point vector unit. The first microarchitecture was informally known as“TrainWreck”, due to the short time available to complete the design with immature design libraries.
Subsequently, a clean microarchitecture for an in-order decoupled RV64 core was developed byAndrew Waterman, Rimas Avižienis, and Yunsup Lee, advised by Krste Asanović, and, continuing
the railway theme, was codenamed “Rocket” after George Stephenson’s successful steam locomotiveVolume I: RISC-V Unprivileged ISA V20191213

157

design. Rocket was written in Chisel, a new hardware design language developed at UC Berkeley.
The IEEE floating-point units used in Rocket were developed by John Hauser, Andrew Waterman,
and Brian Richards. Rocket has since been refined and developed further, and has been fabricated
two more times in 28 nm FDSOI (Raven-2, Raven-3), and five times in IBM 45 nm SOI technology(EOS14, EOS16, EOS18, EOS20, EOS22) for a photonics project. Work is ongoing to make theRocket design available as a parameterized RISC-V processor generator.
EOS14–EOS22 chips include early versions of Hwacha, a 64-bit IEEE floating-point vector unit,
developed by Yunsup Lee, Andrew Waterman, Huy Vo, Albert Ou, Quan Nguyen, and Stephen
Twigg, advised by Krste Asanović. EOS16–EOS22 chips include dual cores with a cache-coherence
protocol developed by Henry Cook and Andrew Waterman, advised by Krste Asanović. EOS14
silicon has successfully run at 1.25 GHz. EOS16 silicon suffered from a bug in the IBM pad libraries.
EOS18 and EOS20 have successfully run at 1.35 GHz.
Contributors to the Raven testchips include Yunsup Lee, Andrew Waterman, Rimas Avižienis,
Brian Zimmer, Jaehwa Kwak, Ruzica Jevtić, Milovan Blagojević, Alberto Puggelli, Steven Bailey,
Ben Keller, Pi-Feng Chiu, Brian Richards, Borivoje Nikolić, and Krste Asanović.
Contributors to the EOS testchips include Yunsup Lee, Rimas Avižienis, Andrew Waterman, Henry
Cook, Huy Vo, Daiwei Li, Chen Sun, Albert Ou, Quan Nguyen, Stephen Twigg, Vladimir Stojanović, and Krste Asanović.
Andrew Waterman and Yunsup Lee developed the C++ ISA simulator “Spike”, used as a goldenmodel in development and named after the golden spike used to celebrate completion of the US
transcontinental railway. Spike has been made available as a BSD open-source project.
Andrew Waterman completed a Master’s thesis with a preliminary design of the RISC-V compressed
instruction set [22].
Various FPGA implementations of the RISC-V have been completed, primarily as part of integrated
demos for the Par Lab project research retreats. The largest FPGA design has 3 cache-coherent
RV64IMA processors running a research operating system. Contributors to the FPGA implementations include Andrew Waterman, Yunsup Lee, Rimas Avižienis, and Krste Asanović.
RISC-V processors have been used in several classes at UC Berkeley. Rocket was used in the Fall
2011 offering of CS250 as a basis for class projects, with Brian Zimmer as TA. For the undergraduate
CS152 class in Spring 2012, Christopher Celio used Chisel to write a suite of educational RV32
processors, named “Sodor” after the island on which “Thomas the Tank Engine” and friends live.
The suite includes a microcoded core, an unpipelined core, and 2, 3, and 5-stage pipelined cores,
and is publicly available under a BSD license. The suite was subsequently updated and used again
in CS152 in Spring 2013, with Yunsup Lee as TA, and in Spring 2014, with Eric Love as TA.
Christopher Celio also developed an out-of-order RV64 design known as BOOM (Berkeley Out-ofOrder Machine), with accompanying pipeline visualizations, that was used in the CS152 classes.
The CS152 classes also used cache-coherent versions of the Rocket core developed by Andrew
Waterman and Henry Cook.
Over the summer of 2013, the RoCC (Rocket Custom Coprocessor) interface was defined to simplify adding custom accelerators to the Rocket core. Rocket and the RoCC interface were used
extensively in the Fall 2013 CS250 VLSI class taught by Jonathan Bachrach, with several student

158

Volume I: RISC-V Unprivileged ISA V20191213

accelerator projects built to the RoCC interface. The Hwacha vector unit has been rewritten as a
RoCC coprocessor.
Two Berkeley undergraduates, Quan Nguyen and Albert Ou, have successfully ported Linux to run
on RISC-V in Spring 2013.
Colin Schmidt successfully completed an LLVM backend for RISC-V 2.0 in January 2014.
Darius Rad at Bluespec contributed soft-float ABI support to the GCC port in March 2014.
John Hauser contributed the definition of the floating-point classification instructions.
We are aware of several other RISC-V core implementations, including one in Verilog by TommyThorn, and one in Bluespec by Rishiyur Nikhil.

Acknowledgments
Thanks to Christopher F. Batten, Preston Briggs, Christopher Celio, David Chisnall, Stefan
Freudenberger, John Hauser, Ben Keller, Rishiyur Nikhil, Michael Taylor, Tommy Thorn, andRobert Watson for comments on the draft ISA version 2.0 specification.

28.4

History from Revision 2.1

Uptake of the RISC-V ISA has been very rapid since the introduction of the frozen version 2.0 in
May 2014, with too much activity to record in a short history section such as this. Perhaps themost important single event was the formation of the non-profit RISC-V Foundation in August
2015. The Foundation will now take over stewardship of the official RISC-V ISA standard, and theofficial website riscv.org is the best place to obtain news and updates on the RISC-V standard.

Acknowledgments
Thanks to Scott Beamer, Allen J. Baum, Christopher Celio, David Chisnall, Paul Clayton, Palmer
Dabbelt, Jan Gray, Michael Hamburg, and John Hauser for comments on the version 2.0 specification.

28.5

History from Revision 2.2

Acknowledgments
Thanks to Jacob Bachmeyer, Alex Bradbury, David Horner, Stefan O’Rear, and Joseph Myers forcomments on the version 2.1 specification.

Volume I: RISC-V Unprivileged ISA V20191213

28.6

159

History for Revision 2.3

Uptake of RISC-V continues at breakneck pace.
John Hauser and Andrew Waterman contributed a hypervisor ISA extension based upon a proposal
from Paolo Bonzini.
Daniel Lustig, Arvind, Krste Asanović, Shaked Flur, Paul Loewenstein, Yatin Manerkar, Luc
Maranget, Margaret Martonosi, Vijayanand Nagarajan, Rishiyur Nikhil, Jonas Oberhauser,
Christopher Pulte, Jose Renau, Peter Sewell, Susmit Sarkar, Caroline Trippel, Muralidaran Vijayaraghavan, Andrew Waterman, Derek Williams, Andrew Wright, and Sizhuo Zhang contributed
the memory consistency model.

28.7

Funding

Development of the RISC-V architecture and implementations has been partially funded by thefollowing sponsors.
• Par Lab: Research supported by Microsoft (Award #024263) and Intel (Award #024894)
funding and by matching funding by U.C. Discovery (Award #DIG07-10227). Additional
support came from Par Lab affiliates Nokia, NVIDIA, Oracle, and Samsung.
• Project Isis: DoE Award DE-SC0003624.
• ASPIRE Lab: DARPA PERFECT program, Award HR0011-12-2-0016. DARPA POEM
program Award HR0011-11-C-0100. The Center for Future Architectures Research (C-FAR),a STARnet center funded by the Semiconductor Research Corporation. Additional support
from ASPIRE industrial sponsor, Intel, and ASPIRE affiliates, Google, Hewlett Packard
Enterprise, Huawei, Nokia, NVIDIA, Oracle, and Samsung.
The content of this paper does not necessarily reflect the position or the policy of the US government
and no official endorsement should be inferred.

160

Volume I: RISC-V Unprivileged ISA V20191213

Appendix A

RVWMO Explanatory Material,
Version 0.1
This section provides more explanation for RVWMO (Chapter 14), using more informal language
and concrete examples. These are intended to clarify the meaning and intent of the axioms andpreserved program order rules. This appendix should be treated as commentary; all normative
material is provided in Chapter 14 and in the rest of the main body of the ISA specification. All
currently known discrepancies are listed in Section A.7. Any other discrepancies are unintentional.

A.1

Why RVWMO?

Memory consistency models fall along a loose spectrum from weak to strong. Weak memory
models allow more hardware implementation flexibility and deliver arguably better performance,
performance per watt, power, scalability, and hardware verification overheads than strong models,at the expense of a more complex programming model. Strong models provide simpler programming
models, but at the cost of imposing more restrictions on the kinds of (non-speculative) hardware
optimizations that can be performed in the pipeline and in the memory system, and in turn imposing
some cost in terms of power, area overhead, and verification burden.
RISC-V has chosen the RVWMO memory model, a variant of release consistency. This places it inbetween the two extremes of the memory model spectrum. The RVWMO memory model enables
architects to build simple implementations, aggressive implementations, implementations embedded
deeply inside a much larger system and subject to complex memory system interactions, or any
number of other possibilities, all while simultaneously being strong enough to support programming
language memory models at high performance.
To facilitate the porting of code from other architectures, some hardware implementations may
choose to implement the Ztso extension, which provides stricter RVTSO ordering semantics bydefault. Code written for RVWMO is automatically and inherently compatible with RVTSO, but
code written assuming RVTSO is not guaranteed to run correctly on RVWMO implementations. In
fact, most RVWMO implementations will (and should) simply refuse to run RVTSO-only binaries.
Each implementation must therefore choose whether to prioritize compatibility with RVTSO code
161

162

Volume I: RISC-V Unprivileged ISA V20191213(e.g., to facilitate porting from x86) or whether to instead prioritize compatibility with other RISCV cores implementing RVWMO.
Some fences and/or memory ordering annotations in code written for RVWMO may become redundant under RVTSO; the cost that the default of RVWMO imposes on Ztso implementations is
the incremental overhead of fetching those fences (e.g., FENCE R,RW and FENCE RW,W) whichbecome no-ops on that implementation. However, these fences must remain present in the code if
compatibility with non-Ztso implementations is desired.

A.2

Litmus Tests

The explanations in this chapter make use of litmus tests, or small programs designed to test or
highlight one particular aspect of a memory model. Figure A.1 shows an example of a litmus testwith two harts. As a convention for this figure and for all figures that follow in this chapter, we
assume that s0–s2 are pre-set to the same value in all harts and that s0 holds the address labeledx, s1 holds y, and s2 holds z, where x, y, and z are disjoint memory locations aligned to 8 byteboundaries. Each figure shows the litmus test code on the left, and a visualization of one particularvalid or invalid execution on the right.

(a)

(b)
(c)

(d)

Hart 0.
.
.
li t1,1
sw t1,0(s0)
.
.
.

(e)

li t2,2
sw t2,0(s0)
.
.
.

.
.
.

lw a0,0(s0).
.
.
li t3,3
sw t3,0(s0).
.
.

Hart 1.
.
.
li t4,4
sw t4,0(s0)
.
.
.

(f)

.
.
.
li t5,5
sw t5,0(s0).
.
.

a: Wx=1
cofr

cob: Wx=2 rf

e: Wx=4

cofr
f: Wx=5
c: Rx=1 co
fr
d: Wx=3

Figure A.1: A sample litmus test and one forbidden execution (a0=1).
Litmus tests are used to understand the implications of the memory model in specific concrete
situations. For example, in the litmus test of Figure A.1, the final value of a0 in the first hart canbe either 2, 4, or 5, depending on the dynamic interleaving of the instruction stream from eachhart at runtime. However, in this example, the final value of a0 in Hart 0 will never be 1 or 3;
intuitively, the value 1 will no longer be visible at the time the load executes, and the value 3 will
not yet be visible by the time the load executes. We analyze this test and many others below.
The diagram shown to the right of each litmus test shows a visual representation of the particular
execution candidate being considered. These diagrams use a notation that is common in the memory
model literature for constraining the set of possible global memory orders that could produce theexecution in question. It is also the basis for the herd models presented in Appendix B.2. This

Volume I: RISC-V Unprivileged ISA V20191213
Edge
rf
co
fr
ppo
fence
addr
ctrl
data

163

Full Name (and explanation)
Reads From (from each store to the loads that return a value written by that store)
Coherence (a total order on the stores to each address)
From-Reads (from each load to co-successors of the store from which the load returned a value)
Preserved Program Order
Orderings enforced by a FENCE instruction
Address Dependency
Control Dependency
Data Dependency

Table A.1: A key for the litmus test diagrams drawn in this appendix
notation is explained in Table A.1. Of the listed relations, rf edges between harts, co edges, fr
edges, and ppo edges directly constrain the global memory order (as do fence, addr, data, and some
ctrl edges, via ppo). Other edges (such as intra-hart rf edges) are informative but do not constrain
the global memory order.
For example, in Figure A.1, a0=1 could occur only if one of the following were true:• (b) appears before (a) in global memory order (and in the coherence order co). However, thisviolates RVWMO PPO rule 1. The co edge from (b) to (a) highlights this contradiction.
• (a) appears before (b) in global memory order (and in the coherence order co). However, in
this case, the Load Value Axiom would be violated, because (a) is not the latest matching
store prior to (c) in program order. The fr edge from (c) to (b) highlights this contradiction.
Since neither of these scenarios satisfies the RVWMO axioms, the outcome a0=1 is forbidden.
Beyond what is described in this appendix, a suite of more than seven thousand litmus tests isavailable at https://github.com/litmus-tests/litmus-tests-riscv.
The litmus tests repository also provides instructions on how to run the litmus tests on RISC-V
hardware and how to compare the results with the operational and axiomatic models.
In the future, we expect to adapt these memory model litmus tests for use as part of the RISC-V
compliance test suite as well.

A.3

Explaining the RVWMO Rules

In this section, we provide explanation and examples for all of the RVWMO rules and axioms.

A.3.1

Preserved Program Order and Global Memory Order

Preserved program order represents the subset of program order that must be respected within
the global memory order. Conceptually, events from the same hart that are ordered by preserved
program order must appear in that order from the perspective of other harts and/or observers.

164

Volume I: RISC-V Unprivileged ISA V20191213

Events from the same hart that are not ordered by preserved program order, on the other hand,
may appear reordered from the perspective of other harts and/or observers.
Informally, the global memory order represents the order in which loads and stores perform. The
formal memory model literature has moved away from specifications built around the concept of
performing, but the idea is still useful for building up informal intuition. A load is said to have
performed when its return value is determined. A store is said to have performed not when it
has executed inside the pipeline, but rather only when its value has been propagated to globally
visible memory. In this sense, the global memory order also represents the contribution of thecoherence protocol and/or the rest of the memory system to interleave the (possibly reordered)memory accesses being issued by each hart into a single total order agreed upon by all harts.
The order in which loads perform does not always directly correspond to the relative age of thevalues those two loads return. In particular, a load b may perform before another load a to the same
address (i.e., b may execute before a, and b may appear before a in the global memory order), but
a may nevertheless return an older value than b. This discrepancy captures (among other things)
the reordering effects of buffering placed between the core and memory. For example, b may havereturned a value from a store in the store buffer, while a may have ignored that younger store andread an older value from memory instead. To account for this, at the time each load performs, thevalue it returns is determined by the load value axiom, not just strictly by determining the mostrecent store to the same address in the global memory order, as described below.

A.3.2

Load Value Axiom
Load Value Axiom: Each byte of each load i returns the value written
to that byte by the store that is the latest in global memory order among
the following stores:
1. Stores that write that byte and that precede i in the global memoryorder
2. Stores that write that byte and that precede i in program order

Preserved program order is not required to respect the ordering of a store followed by a load toan overlapping address. This complexity arises due to the ubiquity of store buffers in nearly all
implementations. Informally, the load may perform (return a value) by forwarding from the store
while the store is still in the store buffer, and hence before the store itself performs (writes back to
globally visible memory). Any other hart will therefore observe the load as performing before thestore.
Consider the litmus test of Figure A.2. When running this program on an implementation withstore buffers, it is possible to arrive at the final outcome a0=1, a1=0, a2=1, a3=0 as follows:• (a) executes and enters the first hart’s private store buffer• (b) executes and forwards its return value 1 from (a) in the store buffer• (c) executes since all previous loads (i.e., (b)) have completed

Volume I: RISC-V Unprivileged ISA V20191213

Hart 0Hart 1
li t1, 1
li t1, 1(a) sw t1,0(s0) (e) sw t1,0(s1)(b) lw a0,0(s0) (f) lw a2,0(s1)(c) fence r,r(g) fence r,r(d) lw a1,0(s1) (h) lw a3,0(s0)Outcome: a0=1, a1=0, a2=1, a3=0

165

a: Wx=1

e: Wy=1

rf

rf

b: Rx=1
fence ppo

fr

fr

d: Ry=0

f: Ry=1
fence ppo
h: Rx=0

Figure A.2: A store buffer forwarding litmus test (outcome permitted)• (d) executes and reads the value 0 from memory• (e) executes and enters the second hart’s private store buffer• (f) executes and forwards its return value 1 from (e) in the store buffer• (g) executes since all previous loads (i.e., (f)) have completed• (h) executes and reads the value 0 from memory• (a) drains from the first hart’s store buffer to memory• (e) drains from the second hart’s store buffer to memory
Therefore, the memory model must be able to account for this behavior.
To put it another way, suppose the definition of preserved program order did include the following
hypothetical rule: memory access a precedes memory access b in preserved program order (andhence also in the global memory order) if a precedes b in program order and a and b are accesses
to the same memory location, a is a write, and b is a read. Call this “Rule X”. Then we get thefollowing:• (a) precedes (b): by rule X• (b) precedes (d): by rule 4• (d) precedes (e): by the load value axiom. Otherwise, if (e) preceded (d), then (d) would be
required to return the value 1. (This is a perfectly legal execution; it’s just not the one inquestion)• (e) precedes (f): by rule X• (f) precedes (h): by rule 4• (h) precedes (a): by the load value axiom, as above.
The global memory order must be a total order and cannot be cyclic, because a cycle would imply
that every event in the cycle happens before itself, which is impossible. Therefore, the execution

166

Volume I: RISC-V Unprivileged ISA V20191213

proposed above would be forbidden, and hence the addition of rule X would forbid implementations
with store buffer forwarding, which would clearly be undesirable.
Nevertheless, even if (b) precedes (a) and/or (f) precedes (e) in the global memory order, the only
sensible possibility in this example is for (b) to return the value written by (a), and likewise for (f)and (e). This combination of circumstances is what leads to the second option in the definition of
the load value axiom. Even though (b) precedes (a) in the global memory order, (a) will still bevisible to (b) by virtue of sitting in the store buffer at the time (b) executes. Therefore, even if (b)precedes (a) in the global memory order, (b) should return the value written by (a) because (a)precedes (b) in program order. Likewise for (e) and (f).

d: Ry=1
(a)
(b)
(c)

Hart 0li t1, 1
sw t1,0(s0)fence w,w
sw t1,0(s1)Outcome:Hart 1
li t1, 1LOOP:(d) lw a0,0(s1)beqz a0, LOOP(e) sw t1,0(s2)(f) lw a1,0(s2)xor a2,a1,a1
add s0,s0,a2(g) lw a2,0(s0)a0=1, a1=1, a2=0

ctrl ppo
a: Wx=1
fence pporf

e: Wz=1
rf ctrlfr

c: Wy=1

f: Rz=1 ctrl
addr ppog: Rx=0

Figure A.3: The “PPOCA” store buffer forwarding litmus test (outcome permitted)
Another test that highlights the behavior of store buffers is shown in Figure A.3. In this example,(d) is ordered before (e) because of the control dependency, and (f) is ordered before (g) because of
the address dependency. However, (e) is not necessarily ordered before (f), even though (f) returns
the value written by (e). This could correspond to the following sequence of events:• (e) executes speculatively and enters the second hart’s private store buffer (but does not drain
to memory)• (f) executes speculatively and forwards its return value 1 from (e) in the store buffer• (g) executes speculatively and reads the value 0 from memory• (a) executes, enters the first hart’s private store buffer, and drains to memory• (b) executes and retires• (c) executes, enters the first hart’s private store buffer, and drains to memory• (d) executes and reads the value 1 from memory• (e), (f), and (g) commit, since the speculation turned out to be correct• (e) drains from the store buffer to memory

Volume I: RISC-V Unprivileged ISA V20191213

A.3.3

167

Atomicity Axiom
Atomicity Axiom (for Aligned Atomics): If r and w are paired load andstore operations generated by aligned LR and SC instructions in a harth, s is a store to byte x, and r returns a value written by s, then s must
precede w in the global memory order, and there can be no store froma hart other than h to byte x following s and preceding w in the global
memory order.

The RISC-V architecture decouples the notion of atomicity from the notion of ordering. Unlike architectures such as TSO, RISC-V atomics under RVWMO do not impose any ordering requirements
by default. Ordering semantics are only guaranteed by the PPO rules that otherwise apply.
RISC-V contains two types of atomics: AMOs and LR/SC pairs. These conceptually behave
differently, in the following way. LR/SC behave as if the old value is brought up to the core,modified, and written back to memory, all while a reservation is held on that memory location.
AMOs on the other hand conceptually behave as if they are performed directly in memory. AMOs
are therefore inherently atomic, while LR/SC pairs are atomic in the slightly different sense thatthe memory location in question will not be modified by another hart during the time the original
hart holds the reservation.
(a) lr.d a0, 0(s0)(b) sdt1, 0(s0)(c) sc.d t2, 0(s0)(a) lr.d a0, 0(s0)(b) sw
t1, 4(s0)(c) sc.d t2, 0(s0)(a) lr.w a0, 0(s0)(b) sw
t1, 4(s0)(c) sc.w t2, 0(s0)(a) lr.w a0, 0(s0)(b) sw
t1, 4(s0)(c) sc.w t2, 8(s0)Figure A.4: In all four (independent) code snippets, the store-conditional (c) is permitted but notguaranteed to succeed
The atomicity axiom forbids stores from other harts from being interleaved in global memory order
between an LR and the SC paired with that LR. The atomicity axiom does not forbid loads frombeing interleaved between the paired operations in program order or in the global memory order,
nor does it forbid stores from the same hart or stores to non-overlapping locations from appearing
between the paired operations in either program order or in the global memory order. For example,
the SC instructions in Figure A.4 may (but are not guaranteed to) succeed. None of those successes
would violate the atomicity axiom, because the intervening non-conditional stores are from the same
hart as the paired load-reserved and store-conditional instructions. This way, a memory systemthat tracks memory accesses at cache line granularity (and which therefore will see the four snippets
of Figure A.4 as identical) will not be forced to fail a store-conditional instruction that happens
to (falsely) share another portion of the same cache line as the memory location being held by thereservation.
The atomicity axiom also technically supports cases in which the LR and SC touch different addresses and/or use different access sizes; however, use cases for such behaviors are expected to
be rare in practice. Likewise, scenarios in which stores from the same hart between an LR/SC

168

Volume I: RISC-V Unprivileged ISA V20191213

pair actually overlap the memory location(s) referenced by the LR or SC are expected to be rarecompared to scenarios where the intervening store may simply fall onto the same cache line.

A.3.4

Progress Axiom
Progress Axiom: No memory operation may be preceded in the global
memory order by an infinite sequence of other memory operations.

The progress axiom ensures a minimal forward progress guarantee. It ensures that stores from one
hart will eventually be made visible to other harts in the system in a finite amount of time, andthat loads from other harts will eventually be able to read those values (or successors thereof).
Without this rule, it would be legal, for example, for a spinlock to spin infinitely on a value, evenwith a store from another hart waiting to unlock the spinlock.
The progress axiom is intended not to impose any other notion of fairness, latency, or quality ofservice onto the harts in a RISC-V implementation. Any stronger notions of fairness are up to therest of the ISA and/or up to the platform and/or device to define and implement.
The forward progress axiom will in almost all cases be naturally satisfied by any standard cachecoherence protocol. Implementations with non-coherent caches may have to provide some othermechanism to ensure the eventual visibility of all stores (or successors thereof) to all harts.

A.3.5

Overlapping-Address Orderings (Rules 1–3)
Rule 1: b is a store, and a and b access overlapping memory addresses
Rule 2: a and b are loads, x is a byte read by both a and b, there is no
store to x between a and b in program order, and a and b return values
for x written by different memory operations
Rule 3: a is generated by an AMO or SC instruction, b is a load, and b
returns a value written by aSame-address orderings where the latter is a store are straightforward: a load or store can neverbe reordered with a later store to an overlapping memory location. From a microarchitecture
perspective, generally speaking, it is difficult or impossible to undo a speculatively reordered store
if the speculation turns out to be invalid, so such behavior is simply disallowed by the model.
Same-address orderings from a store to a later load, on the other hand, do not need to be enforced.
As discussed in Section A.3.2, this reflects the observable behavior of implementations that forward
values from buffered stores to later loads.
Same-address load-load ordering requirements are far more subtle. The basic requirement is thata younger load must not return a value that is older than a value returned by an older load in
the same hart to the same address. This is often known as “CoRR” (Coherence for Read-Readpairs), or as part of a broader “coherence” or “sequential consistency per location” requirement.
Some architectures in the past have relaxed same-address load-load ordering, but in hindsight thisis generally considered to complicate the programming model too much, and so RVWMO requires
CoRR ordering to be enforced. However, because the global memory order corresponds to theVolume I: RISC-V Unprivileged ISA V20191213

169

order in which loads perform rather than the ordering of the values being returned, capturing
CoRR requirements in terms of the global memory order requires a bit of indirection.

(a)
(b)
(c)

Hart 0li t1, 1
sw t1,0(s0)fence w, w
sw t1,0(s1)Outcome:Hart 1
li t2, 2(d) lw a0,0(s1)(e) sw t2,0(s1)(f) lw a1,0(s1)(g) xor t3,a1,a1(h) add s0,s0,t3(i) lw a2,0(s0)a0=1, a1=2, a2=0

a: Wx=1
fence ppo
c: Wy=1

d: Ry=1
rfco

fr ppoe: Wy=2

fr

rf
f: Ry=2
addr ppo
i: Rx=0

Figure A.5: Litmus test MP+fence.w.w+fri-rfi-addr (outcome permitted)
Consider the litmus test of Figure A.5, which is one particular instance of the more general “fri-rfi”
pattern. The term “fri-rfi” refers to the sequence (d), (e), (f): (d) “from-reads” (i.e., reads froman earlier write than) (e) which is the same hart, and (f) reads from (e) which is in the same hart.
From a microarchitectural perspective, outcome a0=1, a1=2, a2=0 is legal (as are various other lesssubtle outcomes). Intuitively, the following would produce the outcome in question:• (d) stalls (for whatever reason; perhaps it’s stalled waiting for some other preceding instruction)• (e) executes and enters the store buffer (but does not yet drain to memory)• (f) executes and forwards from (e) in the store buffer• (g), (h), and (i) execute• (a) executes and drains to memory, (b) executes, and (c) executes and drains to memory• (d) unstalls and executes• (e) drains from the store buffer to memory
This corresponds to a global memory order of (f), (i), (a), (c), (d), (e). Note that even though (f)performs before (d), the value returned by (f) is newer than the value returned by (d). Therefore,
this execution is legal and does not violate the CoRR requirements.
Likewise, if two back-to-back loads return the values written by the same store, then they may also
appear out-of-order in the global memory order without violating CoRR. Note that this is not thesame as saying that the two loads return the same value, since two different stores may write thesame value.
Consider the litmus test of Figure A.6. The outcome a0=1, a1=v, a2=v, a3=0 (where v is some value
written by another hart) can be observed by allowing (g) and (h) to be reordered. This might be170

Volume I: RISC-V Unprivileged ISA V20191213

(a)
(b)
(c)

Hart 0li t1, 1
sw t1,0(s0)fence w, w
sw t1,0(s1)Outcome:Hart 1(d) lw a0,0(s1)(e) xor t2,a0,a0(f) add s4,s2,t2(g) lw a1,0(s4)(h) lw a2,0(s2)(i) xor t3,a2,a2(j) add s0,s0,t3(k) lw a3,0(s0)a0=1, a1=v, a2=v, a3=0

a: Wx=1

d: Ry=1
rf

fence ppo
c: Wy=1

addr ppo
g: Rz=v
po
fr

rf
rf

Wz=v

h: Rz=v
addr ppo
k: Rx=0

Figure A.6: Litmus test RSW (outcome permitted)
done speculatively, and the speculation can be justified by the microarchitecture (e.g., by snooping
for cache invalidations and finding none) because replaying (h) after (g) would return the value
written by the same store anyway. Hence assuming a1 and a2 would end up with the same value
written by the same store anyway, (g) and (h) can be legally reordered. The global memory ordercorresponding to this execution would be (h),(k),(a),(c),(d),(g).
Executions of the test in Figure A.6 in which a1 does not equal a2 do in fact require that (g)appears before (h) in the global memory order. Allowing (h) to appear before (g) in the global
memory order would in that case result in a violation of CoRR, because then (h) would return anolder value than that returned by (g). Therefore, PPO rule 2 forbids this CoRR violation fromoccurring. As such, PPO rule 2 strikes a careful balance between enforcing CoRR in all cases while
simultaneously being weak enough to permit “RSW” and “fri-rfi” patterns that commonly appear
in real microarchitectures.
There is one more overlapping-address rule: PPO rule 3 simply states that a value cannot be
returned from an AMO or SC to a subsequent load until the AMO or SC has (in the case of theSC, successfully) performed globally. This follows somewhat naturally from the conceptual viewthat both AMOs and SC instructions are meant to be performed atomically in memory. However,notably, PPO rule 3 states that hardware may not even non-speculatively forward the value being
stored by an AMOSWAP to a subsequent load, even though for AMOSWAP that store value is
not actually semantically dependent on the previous value in memory, as is the case for the other
AMOs. The same holds true even when forwarding from SC store values that are not semanticallydependent on the value returned by the paired LR.
The three PPO rules above also apply when the memory accesses in question only overlap partially.
This can occur, for example, when accesses of different sizes are used to access the same object.
Note also that the base addresses of two overlapping memory operations need not necessarily be thesame for two memory accesses to overlap. When misaligned memory accesses are being used, theoverlapping-address PPO rules apply to each of the component memory accesses independently.

A.3.6

Fences (Rule 4)
Rule 4: There is a FENCE instruction that orders a before b

Volume I: RISC-V Unprivileged ISA V20191213

171

By default, the FENCE instruction ensures that all memory accesses from instructions preceding
the fence in program order (the “predecessor set”) appear earlier in the global memory order thanmemory accesses from instructions appearing after the fence in program order (the “successor set”).
However, fences can optionally further restrict the predecessor set and/or the successor set to asmaller set of memory accesses in order to provide some speedup. Specifically, fences have PR, PW,
SR, and SW bits which restrict the predecessor and/or successor sets. The predecessor set includes
loads (resp. stores) if and only if PR (resp. PW) is set. Similarly, the successor set includes loads(resp. stores) if and only if SR (resp. SW) is set.
The FENCE encoding currently has nine non-trivial combinations of the four bits PR, PW, SR,
and SW, plus one extra encoding FENCE.TSO which facilitates mapping of “acquire+release” or
RVTSO semantics. The remaining seven combinations have empty predecessor and/or successor
sets and hence are no-ops. Of the ten non-trivial options, only six are commonly used in practice:• FENCE RW,RW• FENCE.TSO• FENCE RW,W
• FENCE R,RW
• FENCE R,R• FENCE W,W
FENCE instructions using any other combination of PR, PW, SR, and SW are reserved. Westrongly recommend that programmers stick to these six. Other combinations may have unknown
or unexpected interactions with the memory model.
Finally, we note that since RISC-V uses a multi-copy atomic memory model, programmers can reason about fences bits in a thread-local manner. There is no complex notion of “fence cumulativity”
as found in memory models that are not multi-copy atomic.

A.3.7

Explicit Synchronization (Rules 5–8)
Rule 5: a has an acquire annotation
Rule 6: b has a release annotation
Rule 7: a and b both have RCsc annotations
Rule 8: a is paired with b

An acquire operation, as would be used at the start of a critical section, requires all memory
operations following the acquire in program order to also follow the acquire in the global memoryorder. This ensures, for example, that all loads and stores inside the critical section are up todate with respect to the synchronization variable being used to protect it. Acquire ordering canbe enforced in one of two ways: with an acquire annotation, which enforces ordering with respect
to just the synchronization variable itself, or with a FENCE R,RW, which enforces ordering withrespect to all previous loads.

172

Volume I: RISC-V Unprivileged ISA V20191213
sd
x1, (a1)# Arbitrary unrelated store
ldx2, (a2)# Arbitrary unrelated load
lit0, 1
# Initialize swap value.
again:
amoswap.w.aq t0, t0, (a0) # Attempt to acquire lock.
bnez
t0, again# Retry if held.
# ...
# Critical section.
# ...
amoswap.w.rl x0, x0, (a0) # Release lock by storing 0.
sdx3, (a3)# Arbitrary unrelated store
ldx4, (a4)# Arbitrary unrelated load

Figure A.7: A spinlock with atomics
Consider Figure A.7. Because this example uses aq, the loads and stores in the critical section are
guaranteed to appear in the global memory order after the AMOSWAP used to acquire the lock.
However, assuming a0, a1, and a2 point to different memory locations, the loads and stores in thecritical section may or may not appear after the “Arbitrary unrelated load” at the beginning of theexample in the global memory order.
sd
x1, (a1)# Arbitrary unrelated store
ldx2, (a2)# Arbitrary unrelated load
lit0, 1
# Initialize swap value.
again:
amoswap.w
t0, t0, (a0) # Attempt to acquire lock.
fence
r, rw
# Enforce "acquire" memory orderingbnez
t0, again# Retry if held.
# ...
# Critical section.
# ...
fence
rw, w
# Enforce "release" memory ordering
amoswap.w
x0, x0, (a0) # Release lock by storing 0.
sdx3, (a3)# Arbitrary unrelated store
ldx4, (a4)# Arbitrary unrelated load

Figure A.8: A spinlock with fences
Now, consider the alternative in Figure A.8. In this case, even though the AMOSWAP does
not enforce ordering with an aq bit, the fence nevertheless enforces that the acquire AMOSWAP
appears earlier in the global memory order than all loads and stores in the critical section. Note,however, that in this case, the fence also enforces additional orderings: it also requires that the“Arbitrary unrelated load” at the start of the program appears earlier in the global memory orderthan the loads and stores of the critical section. (This particular fence does not, however, enforce
any ordering with respect to the “Arbitrary unrelated store” at the start of the snippet.) In thisway, fence-enforced orderings are slightly coarser than orderings enforced by .aq.

Volume I: RISC-V Unprivileged ISA V20191213

173

Release orderings work exactly the same as acquire orderings, just in the opposite direction. Releasesemantics require all loads and stores preceding the release operation in program order to also
precede the release operation in the global memory order. This ensures, for example, that memory
accesses in a critical section appear before the lock-releasing store in the global memory order.
Just as for acquire semantics, release semantics can be enforced using release annotations or with a
FENCE RW,W operation. Using the same examples, the ordering between the loads and stores in
the critical section and the “Arbitrary unrelated store” at the end of the code snippet is enforced
only by the FENCE RW,W in Figure A.8, not by the rl in Figure A.7.
With RCpc annotations alone, store-release-to-load-acquire ordering is not enforced. This facilitates
the porting of code written under the TSO and/or RCpc memory models. To enforce store-releaseto-load-acquire ordering, the code must use store-release-RCsc and load-acquire-RCsc operations sothat PPO rule 7 applies. RCpc alone is sufficient for many use cases in C/C++ but is insufficientfor many other use cases in C/C++, Java, and Linux, to name just a few examples; see Section A.5
for details.
PPO rule 8 indicates that an SC must appear after its paired LR in the global memory order.
This will follow naturally from the common use of LR/SC to perform an atomic read-modify-write
operation due to the inherent data dependency. However, PPO rule 8 also applies even when thevalue being stored does not syntactically depend on the value returned by the paired LR.
Lastly, we note that just as with fences, programmers need not worry about “cumulativity” whenanalyzing ordering annotations.

A.3.8

Syntactic Dependencies (Rules 9–11)
Rule 9: b has a syntactic address dependency on a
Rule 10: b has a syntactic data dependency on a
Rule 11: b is a store, and b has a syntactic control dependency on a

Dependencies from a load to a later memory operation in the same hart are respected by the
RVWMO memory model. The Alpha memory model was notable for choosing not to enforce theordering of such dependencies, but most modern hardware and software memory models consider
allowing dependent instructions to be reordered too confusing and counterintuitive. Furthermore,
modern code sometimes intentionally uses such dependencies as a particularly lightweight ordering
enforcement mechanism.
The terms in Section 14.1 work as follows. Instructions are said to carry dependencies from theirsource register(s) to their destination register(s) whenever the value written into each destination
register is a function of the source register(s). For most instructions, this means that the destination register(s) carry a dependency from all source register(s). However, there are a few notable
exceptions. In the case of memory instructions, the value written into the destination register ultimately comes from the memory system rather than from the source register(s) directly, and so thisbreaks the chain of dependencies carried from the source register(s). In the case of unconditional
jumps, the value written into the destination register comes from the current pc (which is neverconsidered a source register by the memory model), and so likewise, JALR (the only jump with asource register) does not carry a dependency from rs1 to rd.

174

Volume I: RISC-V Unprivileged ISA V20191213(a) fadd f3,f1,f2(b) fadd f6,f4,f5(c) csrrs a0,fflags,x0

Figure A.9: (c) has a syntactic dependency on both (a) and (b) via fflags, a destination registerthat both (a) and (b) implicitly accumulate into
The notion of accumulating into a destination register rather than writing into it reflects the
behavior of CSRs such as fflags. In particular, an accumulation into a register does not clobber
any previous writes or accumulations into the same register. For example, in Figure A.9, (c) has asyntactic dependency on both (a) and (b).
Like other modern memory models, the RVWMO memory model uses syntactic rather than semantic dependencies. In other words, this definition depends on the identities of the registers being
accessed by different instructions, not the actual contents of those registers. This means that anaddress, control, or data dependency must be enforced even if the calculation could seemingly be“optimized away”. This choice ensures that RVWMO remains compatible with code that uses these
false syntactic dependencies as a lightweight ordering mechanism.
ld a1,0(s0)xor a2,a1,a1
add s1,s1,a2
ld a5,0(s1)Figure A.10: A syntactic address dependency
For example, there is a syntactic address dependency from the memory operation generated by the
first instruction to the memory operation generated by the last instruction in Figure A.10, eventhough a1 XOR a1 is zero and hence has no effect on the address accessed by the second load.
The benefit of using dependencies as a lightweight synchronization mechanism is that the ordering
enforcement requirement is limited only to the specific two instructions in question. Other nondependent instructions may be freely-reordered by aggressive implementations. One alternative
would be to use a load-acquire, but this would enforce ordering for the first load with respect toall subsequent instructions. Another would be to use a FENCE R,R, but this would include allprevious and all subsequent loads, making this option more expensive.
lw x1,0(x2)bne x1,x0,next
sw x3,0(x4)next: sw x5,0(x6)Figure A.11: A syntactic control dependency
Control dependencies behave differently from address and data dependencies in the sense that acontrol dependency always extends to all instructions following the original target in program order.
Consider Figure A.11: the instruction at next will always execute, but the memory operation
generated by that last instruction nevertheless still has a control dependency from the memory
operation generated by the first instruction.

Volume I: RISC-V Unprivileged ISA V20191213

175

lw x1,0(x2)bne x1,x0,next
next: sw x3,0(x4)Figure A.12: Another syntactic control dependency
Likewise, consider Figure A.12. Even though both branch outcomes have the same target, there
is still a control dependency from the memory operation generated by the first instruction in thissnippet to the memory operation generated by the last instruction. This definition of control
dependency is subtly stronger than what might be seen in other contexts (e.g., C++), but it
conforms with standard definitions of control dependencies in the literature.
Notably, PPO rules 9–11 are also intentionally designed to respect dependencies that originate
from the output of a successful store-conditional instruction. Typically, an SC instruction will befollowed by a conditional branch checking whether the outcome was successful; this implies that
there will be a control dependency from the store operation generated by the SC instruction to any
memory operations following the branch. PPO rule 11 in turn implies that any subsequent store
operations will appear later in the global memory order than the store operation generated by the
SC. However, since control, address, and data dependencies are defined over memory operations,and since an unsuccessful SC does not generate a memory operation, no order is enforced between
unsuccessful SC and its dependent instructions. Moreover, since SC is defined to carry dependencies
from its source registers to rd only when the SC is successful, an unsuccessful SC has no effect on
the global memory order.

a: Rx=0po
Initial values:

(a)
(b)
(c)
(d)

0(s0)=1; 0(s1)=1

Hart 0Hart 1
ld a0,0(s0)(e) ld a3,0(s2)lr a1,0(s1)(f) sd a3,0(s0)sc a2,a0,0(s1)sd a2,0(s2)Outcome: a0=0, a3=0

e: Ry=0
rf

data ppob: Rz*=0ppodata ppo
f: Wx=0

rf

c: Wz*=0
data ppod: Wy=0

Figure A.13: A variant of the LB litmus test (outcome forbidden)
In addition, the choice to respect dependencies originating at store-conditional instructions ensuresthat certain out-of-thin-air-like behaviors will be prevented. Consider Figure A.13. Suppose ahypothetical implementation could occasionally make some early guarantee that a store-conditional
operation will succeed. In this case, (c) could return 0 to a2 early (before actually executing),
allowing the sequence (d), (e), (f), (a), and then (b) to execute, and then (c) might execute(successfully) only at that point. This would imply that (c) writes its own success value to 0(s1)!
Fortunately, this situation and others like it are prevented by the fact that RVWMO respects
dependencies originating at the stores generated by successful SC instructions.

176

Volume I: RISC-V Unprivileged ISA V20191213

We also note that syntactic dependencies between instructions only have any force when theytake the form of a syntactic address, control, and/or data dependency. For example: a syntactic
dependency between two “F” instructions via one of the “accumulating CSRs” in Section 14.3 does
not imply that the two “F” instructions must be executed in order. Such a dependency would only
serve to ultimately set up later a dependency from both “F” instructions to a later CSR instructionaccessing the CSR flag in question.

A.3.9

Pipeline Dependencies (Rules 12–13)
Rule 12: b is a load, and there exists some store m between a and b inprogram order such that m has an address or data dependency on a,and b returns a value written by mRule 13: b is a store, and there exists some instruction m between a andb in program order such that m has an address dependency on ad: Ry=1
data ppo
(a)
(b)
(c)

Hart 0li t1, 1
sw t1,0(s0)fence w, w
sw t1,0(s1)Outcome:Hart 1(d) lw a0, 0(s1)(e) sw a0, 0(s2)(f) lw a1, 0(s2)xor a2,a1,a1
add s0,s0,a2(g) lw a3,0(s0)a0=1, a3=0

a: Wx=1
fence ppo
c: Wy=1

e: Wz=1 ppo

rf
fr

rf
f: Rz=1
addr ppog: Rx=0

Figure A.14: Because of PPO rule 12 and the data dependency from (d) to (e), (d) must also
precede (f) in the global memory order (outcome forbidden)
PPO rules 12 and 13 reflect behaviors of almost all real processor pipeline implementations. Rule 12
states that a load cannot forward from a store until the address and data for that store are known.
Consider Figure A.14: (f) cannot be executed until the data for (e) has been resolved, because (f)must return the value written by (e) (or by something even later in the global memory order), andthe old value must not be clobbered by the writeback of (e) before (d) has had a chance to perform.
Therefore, (f) will never perform before (d) has performed.
If there were another store to the same address in between (e) and (f), as in Figure A.15, then (f)would no longer be dependent on the data of (e) being resolved, and hence the dependency of (f)on (d), which produces the data for (e), would be broken.
Rule 13 makes a similar observation to the previous rule: a store cannot be performed at memory
until all previous loads that might access the same address have themselves been performed. Sucha load must appear to execute before the store, but it cannot do so if the store were to overwrite
the value in memory before the load had a chance to read the old value. Likewise, a store generally
cannot be performed until it is known that preceding instructions will not cause an exception due

Volume I: RISC-V Unprivileged ISA V20191213

177

d: Ry=1
data ppo

(a)
(b)
(c)

Hart 0li t1, 1
sw t1,0(s0)fence w, w
sw t1,0(s1)Outcome:Hart 1
li t1, 1(d) lw a0, 0(s1)(e) sw a0, 0(s2)(f) sw t1, 0(s2)(g) lw a1, 0(s2)xor a2,a1,a1
add s0,s0,a2(h) lw a3,0(s0)a0=1, a3=0

rf
a: Wx=1
fence ppo
c: Wy=1

e: Wz=1
co ppof: Wz=1

fr

rf
g: Rz=1
addr ppo
h: Rx=0

Figure A.15: Because of the extra store between (e) and (g), (d) no longer necessarily precedes (g)(outcome permitted)
to failed address resolution, and in this sense, rule 13 can be seen as somewhat of a special case ofrule 11.

a: Ry=1
Hart 0(a)(b)(c)

lw a0,0(s0)fence rw,rw
sw s2,0(s1)Outcome:Hart 1
li t1, 1(d) lw a1, 0(s1)(e) lw a2, 0(a1)(f) sw t1, 0(s0)a0=1, a1=t

fence ppo
c: Wx=t

d: Rx=trf
rf

addr ppo
e: Rt=v
ppo
po
f: Wy=1

Figure A.16: Because of the address dependency from (d) to (e), (d) also precedes (f) (outcome
forbidden)
Consider Figure A.16: (f) cannot be executed until the address for (e) is resolved, because it may
turn out that the addresses match; i.e., that a1=s0. Therefore, (f) cannot be sent to memory before(d) has executed and confirmed whether the addresses do indeed overlap.

A.4

Beyond Main Memory

RVWMO does not currently attempt to formally describe how FENCE.I, SFENCE.VMA, I/O
fences, and PMAs behave. All of these behaviors will be described by future formalizations. In themeantime, the behavior of FENCE.I is described in Section 2.7, the behavior of SFENCE.VMA is178

Volume I: RISC-V Unprivileged ISA V20191213

described in the RISC-V Instruction Set Privileged Architecture Manual, and the behavior of I/O
fences and the effects of PMAs are described below.

A.4.1

Coherence and Cacheability

The RISC-V Privileged ISA defines Physical Memory Attributes (PMAs) which specify, among
other things, whether portions of the address space are coherent and/or cacheable. See the RISC-V
Privileged ISA Specification for the complete details. Here, we simply discuss how the various
details in each PMA relate to the memory model:• Main memory vs. I/O, and I/O memory ordering PMAs: the memory model as defined applies
to main memory regions. I/O ordering is discussed below.
• Supported access types and atomicity PMAs: the memory model is simply applied on top ofwhatever primitives each region supports.
• Cacheability PMAs: the cacheability PMAs in general do not affect the memory model.
Non-cacheable regions may have more restrictive behavior than cacheable regions, but theset of allowed behaviors does not change regardless. However, some platform-specific and/or
device-specific cacheability settings may differ.
• Coherence PMAs: The memory consistency model for memory regions marked as noncoherent in PMAs is currently platform-specific and/or device-specific: the load-value axiom,
the atomicity axiom, and the progress axiom all may be violated with non-coherent memory.
Note however that coherent memory does not require a hardware cache coherence protocol.
The RISC-V Privileged ISA Specification suggests that hardware-incoherent regions of main
memory are discouraged, but the memory model is compatible with hardware coherence, software coherence, implicit coherence due to read-only memory, implicit coherence due to only
one agent having access, or otherwise.
• Idempotency PMAs: Idempotency PMAs are used to specify memory regions for which loads
and/or stores may have side effects, and this in turn is used by the microarchitecture to
determine, e.g., whether prefetches are legal. This distinction does not affect the memory
model.

A.4.2

I/O Ordering

For I/O, the load value axiom and atomicity axiom in general do not apply, as both reads andwrites might have device-specific side effects and may return values other than the value “written”
by the most recent store to the same address. Nevertheless, the following preserved program orderrules still generally apply for accesses to I/O memory: memory access a precedes memory access bin global memory order if a precedes b in program order and one or more of the following holds:
1. a precedes b in preserved program order as defined in Chapter 14, with the exception that
acquire and release ordering annotations apply only from one memory operation to anothermemory operation and from one I/O operation to another I/O operation, but not from amemory operation to an I/O nor vice versa

Volume I: RISC-V Unprivileged ISA V20191213

179

2. a and b are accesses to overlapping addresses in an I/O region
3. a and b are accesses to the same strongly-ordered I/O region
4. a and b are accesses to I/O regions, and the channel associated with the I/O region accessedby either a or b is channel 1
5. a and b are accesses to I/O regions associated with the same channel (except for channel 0)
Note that the FENCE instruction distinguishes between main memory operations and I/O operations in its predecessor and successor sets. To enforce ordering between I/O operations and main
memory operations, code must use a FENCE with PI, PO, SI, and/or SO, plus PR, PW, SR,
and/or SW. For example, to enforce ordering between a write to main memory and an I/O write
to a device register, a FENCE W,O or stronger is needed.
sd t0, 0(a0)fence w,osd a0, 0(a1)Figure A.17: Ordering memory and I/O accesses
When a fence is in fact used, implementations must assume that the device may attempt to accessmemory immediately after receiving the MMIO signal, and subsequent memory accesses from thatdevice to memory must observe the effects of all accesses ordered prior to that MMIO operation. In
other words, in Figure A.17, suppose 0(a0) is in main memory and 0(a1) is the address of a device
register in I/O memory. If the device accesses 0(a0) upon receiving the MMIO write, then thatload must conceptually appear after the first store to 0(a0) according to the rules of the RVWMO
memory model. In some implementations, the only way to ensure this will be to require that thefirst store does in fact complete before the MMIO write is issued. Other implementations may
find ways to be more aggressive, while others still may not need to do anything different at all for
I/O and main memory accesses. Nevertheless, the RVWMO memory model does not distinguishbetween these options; it simply provides an implementation-agnostic mechanism to specify theorderings that must be enforced.
Many architectures include separate notions of “ordering” and “completion” fences, especially as it
relates to I/O (as opposed to regular main memory). Ordering fences simply ensure that memory
operations stay in order, while completion fences ensure that predecessor accesses have all completed
before any successors are made visible. RISC-V does not explicitly distinguish between orderingand completion fences. Instead, this distinction is simply inferred from different uses of the FENCE
bits.
For implementations that conform to the RISC-V Unix Platform Specification, I/O devices andDMA operations are required to access memory coherently and via strongly-ordered I/O channels.
Therefore, accesses to regular main memory regions that are concurrently accessed by external
devices can also use the standard synchronization mechanisms. Implementations that do not conform to the Unix Platform Specification and/or in which devices do not access memory coherently
will need to use mechanisms (which are currently platform-specific or device-specific) to enforce
coherency.
I/O regions in the address space should be considered non-cacheable regions in the PMAs for thoseregions. Such regions can be considered coherent by the PMA if they are not cached by any agent.

180

Volume I: RISC-V Unprivileged ISA V20191213

The ordering guarantees in this section may not apply beyond a platform-specific boundary between
the RISC-V cores and the device. In particular, I/O accesses sent across an external bus (e.g., PCIe)
may be reordered before they reach their ultimate destination. Ordering must be enforced in suchsituations according to the platform-specific rules of those external devices and buses.

A.5

Code Porting and Mapping Guidelines
x86/TSO Operation
Load
Store
Atomic RMW
Fence

RVWMO Mappingl{b|h|w|d}; fence r,rw
fence rw,w; s{b|h|w|d}amo<op>.{w|d}.aqrl OR
loop: lr.{w|d}.aq; <op>; sc.{w|d}.aqrl; bnez loop
fence rw,rw

Table A.2: Mappings from TSO operations to RISC-V operations
Table A.2 provides a mapping from TSO memory operations onto RISC-V memory instructions.
Normal x86 loads and stores are all inherently acquire-RCpc and release-RCpc operations: TSO
enforces all load-load, load-store, and store-store ordering by default. Therefore, under RVWMO,
all TSO loads must be mapped onto a load followed by FENCE R,RW, and all TSO stores must
be mapped onto FENCE RW,W followed by a store. TSO atomic read-modify-writes and x86
instructions using the LOCK prefix are fully-ordered and can be implemented either via an AMO
with both aq and rl set, or via an LR with aq set, the arithmetic operation in question, an SC withboth aq and rl set, and a conditional branch checking the success condition. In the latter case, therl annotation on the LR turns out (for non-obvious reasons) to be redundant and can be omitted.
Alternatives to Table A.2 are also possible. A TSO store can be mapped onto AMOSWAP with rl
set. However, since RVWMO PPO Rule 3 forbids forwarding of values from AMOs to subsequentloads, the use of AMOSWAP for stores may negatively affect performance. A TSO load can bemapped using LR with aq set: all such LR instructions will be unpaired, but that fact in and of itself
does not preclude the use of LR for loads. However, again, this mapping may also negatively affectperformance if it puts more pressure on the reservation mechanism than was originally intended.
Power Operation
Load
Load-Reserve
Store
Store-Conditional
lwsyncsync
isync

RVWMO Mappingl{b|h|w|d}lr.{w|d}s{b|h|w|d}sc.{w|d}fence.tso
fence rw,rw
fence.i; fence r,rTable A.3: Mappings from Power operations to RISC-V operations
Table A.3 provides a mapping from Power memory operations onto RISC-V memory instructions.
Power ISYNC maps on RISC-V to a FENCE.I followed by a FENCE R,R; the latter fence isVolume I: RISC-V Unprivileged ISA V20191213

181

needed because ISYNC is used to define a “control+control fence” dependency that is not present
in RVWMO.
ARM Operation
Load
Load-Acquire
Load-Exclusive
Load-Acquire-Exclusive
Store
Store-Release
Store-Exclusive
Store-Release-Exclusive
dmb
dmb.lddmb.stisb

RVWMO Mappingl{b|h|w|d}fence rw, rw; l{b|h|w|d}; fence r,rw
lr.{w|d}lr.{w|d}.aqrl
s{b|h|w|d}fence rw,w; s{b|h|w|d}sc.{w|d}sc.{w|d}.rl
fence rw,rw
fence r,rw
fence w,w
fence.i; fence r,rTable A.4: Mappings from ARM operations to RISC-V operations
Table A.4 provides a mapping from ARM memory operations onto RISC-V memory instructions.
Since RISC-V does not currently have plain load and store opcodes with aq or rl annotations, ARM
load-acquire and store-release operations should be mapped using fences instead. Furthermore, inorder to enforce store-release-to-load-acquire ordering, there must be a FENCE RW,RW between
the store-release and load-acquire; Table A.4 enforces this by always placing the fence in front ofeach acquire operation. ARM load-exclusive and store-exclusive instructions can likewise map onto
their RISC-V LR and SC equivalents, but instead of placing a FENCE RW,RW in front of an LRwith aq set, we simply also set rl instead. ARM ISB maps on RISC-V to FENCE.I followed by
FENCE R,R similarly to how ISYNC maps for Power.
Table A.5 provides a mapping of Linux memory ordering macros onto RISC-V memory instructions.
The Linux fences dma rmb() and dma wmb() map onto FENCE R,R and FENCE W,W, respectively,
since the RISC-V Unix Platform requires coherent DMA, but would be mapped onto FENCE RI,RI
and FENCE WO,WO, respectively, on a platform with non-coherent DMA. Platforms with noncoherent DMA may also require a mechanism by which cache lines can be flushed and/or invalidated.
Such mechanisms will be device-specific and/or standardized in a future extension to the ISA.
The Linux mappings for release operations may seem stronger than necessary, but these mappings
are needed to cover some cases in which Linux requires stronger orderings than the more intuitive
mappings would provide. In particular, as of the time this text is being written, Linux is actively
debating whether to require load-load, load-store, and store-store orderings between accesses in one
critical section and accesses in a subsequent critical section in the same hart and protected by thesame synchronization object. Not all combinations of FENCE RW,W/FENCE R,RW mappings
with aq/rl mappings combine to provide such orderings. There are a few ways around this problem,
including:
1. Always use FENCE RW,W/FENCE R,RW, and never use aq/rl. This suffices but is undesirable, as it defeats the purpose of the aq/rl modifiers.

182

Volume I: RISC-V Unprivileged ISA V20191213
Linux Operation
smp mb()smp rmb()
smp wmb()
dma rmb()
dma wmb()
mb()
rmb()
wmb()
smp load acquire()
smp store release()
Linux Constructatomic <op> relaxedatomic <op> acquire
atomic <op> releaseatomic <op>Linux Constructatomic <op> relaxedatomic <op> acquire
atomic <op> releaseatomic <op>

RVWMO Mapping
fence rw,rw
fence r,r
fence w,w
fence r,r
fence w,w
fence iorw,iorw
fence ri,ri
fence wo,wo
l{b|h|w|d}; fence r,rw
fence.tso; s{b|h|w|d}
RVWMO AMO Mapping
amo<op>.{w|d}amo<op>.{w|d}.aq
amo<op>.{w|d}.rl
amo<op>.{w|d}.aqrl
RVWMO LR/SC Mapping
loop: lr.{w|d}; <op>; sc.{w|d}; bnez loop
loop: lr.{w|d}.aq; <op>; sc.{w|d}; bnez loop
loop: lr.{w|d}; <op>; sc.{w|d}.aqrl∗ ; bnez loop OR
fence.tso; loop: lr.{w|d}; <op>; sc.{w|d}∗ ; bnez loop
loop: lr.{w|d}.aq; <op>; sc.{w|d}.aqrl; bnez loop

Table A.5: Mappings from Linux memory primitives to RISC-V primitives. Other constructs (suchas spinlocks) should follow accordingly. Platforms or devices with non-coherent DMA may needadditional synchronization (such as cache flush or invalidate mechanisms); currently any such extra
synchronization will be device-specific.
2. Always use aq/rl, and never use FENCE RW,W/FENCE R,RW. This does not currently work
due to the lack of load and store opcodes with aq and rl modifiers.
3. Strengthen the mappings of release operations such that they would enforce sufficient orderings in the presence of either type of acquire mapping. This is the currently-recommended
solution, and the one shown in Table A.5.

Linux code:(a) int r0 = *x;(bc) spin_unlock(y, 0);...
...
(d) spin_lock(y);(e) int r1 = *z;

RVWMO Mapping:(a) lw
a0, 0(s0)(b) fence.tso // vs. fence rw,w(c) sdx0,0(s1)...
loop:(d) amoswap.d.aq a1,t1,0(s1)bnez
a1,loop(e) lwa2,0(s2)

Figure A.18: Orderings between critical sections in Linux

Volume I: RISC-V Unprivileged ISA V20191213

183

For example, the critical section ordering rule currently being debated by the Linux community
would require (a) to be ordered before (e) in Figure A.18. If that will indeed be required, then it
would be insufficient for (b) to map as FENCE RW,W. That said, these mappings are subject tochange as the Linux Kernel Memory Model evolves.
C/C++ ConstructNon-atomic load
atomic load(memory order relaxed)
atomic load(memory order acquire)atomic load(memory order seq cst)
Non-atomic store
atomic store(memory order relaxed)
atomic store(memory order release)atomic store(memory order seq cst)
atomic thread fence(memory order acquire)atomic thread fence(memory order release)atomic thread fence(memory order acq rel)atomic thread fence(memory order seq cst)
C/C++ Constructatomic <op>(memory order relaxed)
atomic <op>(memory order acquire)atomic <op>(memory order release)atomic <op>(memory order acq rel)atomic <op>(memory order seq cst)
C/C++ Constructatomic <op>(memory order relaxed)
atomic <op>(memory order acquire)atomic <op>(memory order release)atomic <op>(memory order acq rel)atomic <op>(memory order seq cst)

RVWMO Mappingl{b|h|w|d}l{b|h|w|d}l{b|h|w|d}; fence r,rw
fence rw,rw; l{b|h|w|d}; fence r,rws{b|h|w|d}s{b|h|w|d}fence rw,w; s{b|h|w|d}fence rw,w; s{b|h|w|d}fence r,rw
fence rw,w
fence.tso
fence rw,rw
RVWMO AMO Mapping
amo<op>.{w|d}amo<op>.{w|d}.aq
amo<op>.{w|d}.rl
amo<op>.{w|d}.aqrl
amo<op>.{w|d}.aqrl
RVWMO LR/SC Mapping
loop: lr.{w|d}; <op>; sc.{w|d};bnez loop
loop: lr.{w|d}.aq; <op>; sc.{w|d};bnez loop
loop: lr.{w|d}; <op>; sc.{w|d}.rl;bnez loop
loop: lr.{w|d}.aq; <op>; sc.{w|d}.rl;bnez loop
loop: lr.{w|d}.aqrl; <op>;sc.{w|d}.rl; bnez loop

Table A.6: Mappings from C/C++ primitives to RISC-V primitives.
Table A.6 provides a mapping of C11/C++11 atomic operations onto RISC-V memory instructions. If load and store opcodes with aq and rl modifiers are introduced, then the mappingsin Table A.7 will suffice. Note however that the two mappings only interoperate correctly if
atomic <op>(memory order seq cst) is mapped using an LR that has both aq and rl set.
Any AMO can be emulated by an LR/SC pair, but care must be taken to ensure that any PPO
orderings that originate from the LR are also made to originate from the SC, and that any PPO
orderings that terminate at the SC are also made to terminate at the LR. For example, the LR mustalso be made to respect any data dependencies that the AMO has, given that load operations do not184Volume I: RISC-V Unprivileged ISA V20191213
C/C++ Construct
RVWMO Mapping
Non-atomic load
l{b|h|w|d}
atomic load(memory order relaxed)l{b|h|w|d}
atomic load(memory order acquire)l{b|h|w|d}.aq
atomic load(memory order seq cst)l{b|h|w|d}.aq
Non-atomic stores{b|h|w|d}
atomic store(memory order relaxed)s{b|h|w|d}
atomic store(memory order release)s{b|h|w|d}.rl
atomic store(memory order seq cst)s{b|h|w|d}.rl
atomic thread fence(memory order acquire) fence r,rw
atomic thread fence(memory order release) fence rw,w
atomic thread fence(memory order acq rel) fence.tso
atomic thread fence(memory order seq cst) fence rw,rw
C/C++ Construct
RVWMO AMO Mapping
atomic <op>(memory order relaxed)amo<op>.{w|d}atomic <op>(memory order acquire)amo<op>.{w|d}.aq
atomic <op>(memory order release)amo<op>.{w|d}.rl
atomic <op>(memory order acq rel)amo<op>.{w|d}.aqrl
atomic <op>(memory order seq cst)
amo<op>.{w|d}.aqrl
C/C++ Construct
RVWMO LR/SC Mapping
atomic <op>(memory order relaxed)
lr.{w|d}; <op>; sc.{w|d}atomic <op>(memory order acquire)lr.{w|d}.aq; <op>; sc.{w|d}atomic <op>(memory order release)lr.{w|d}; <op>; sc.{w|d}.rl
atomic <op>(memory order acq rel)lr.{w|d}.aq; <op>; sc.{w|d}.rl
atomic <op>(memory order seq cst)
lr.{w|d}.aq∗ ; <op>; sc.{w|d}.rl∗ must be lr.{w|d}.aqrl in order to interoperate with code mapped per Table A.6

Table A.7: Hypothetical mappings from C/C++ primitives to RISC-V primitives, if native loadacquire and store-release opcodes are introduced.
otherwise have any notion of a data dependency. Likewise, the effect a FENCE R,R elsewhere in
the same hart must also be made to apply to the SC, which would not otherwise respect that fence.
The emulator may achieve this effect by simply mapping AMOs onto lr.aq; <op>; sc.aqrl,
matching the mapping used elsewhere for fully-ordered atomics.

A.6

Implementation Guidelines

The RVWMO and RVTSO memory models by no means preclude microarchitectures from employing sophisticated speculation techniques or other forms of optimization in order to deliver higher
performance. The models also do not impose any requirement to use any one particular cachehierarchy, nor even to use a cache coherence protocol at all. Instead, these models only specify the
behaviors that can be exposed to software. Microarchitectures are free to use any pipeline design,
any coherent or non-coherent cache hierarchy, any on-chip interconnect, etc., as long as the design
only admits executions that satisfy the memory model rules. That said, to help people understandVolume I: RISC-V Unprivileged ISA V20191213

185

the actual implementations of the memory model, in this section we provide some guidelines on
how architects and programmers should interpret the models’ rules.
Both RVWMO and RVTSO are multi-copy atomic (or “other-multi-copy-atomic”): any store valuethat is visible to a hart other than the one that originally issued it must also be conceptually visible
to all other harts in the system. In other words, harts may forward from their own previous stores
before those stores have become globally visible to all harts, but no early inter-hart forwarding ispermitted. Multi-copy atomicity may be enforced in a number of ways. It might hold inherently due
to the physical design of the caches and store buffers, it may be enforced via a single-writer/multiplereader cache coherence protocol, or it might hold due to some other mechanism.
Although multi-copy atomicity does impose some restrictions on the microarchitecture, it is one of
the key properties keeping the memory model from becoming extremely complicated. For example,
a hart may not legally forward a value from a neighbor hart’s private store buffer (unless of course
it is done in such a way that no new illegal behaviors become architecturally visible). Nor may
a cache coherence protocol forward a value from one hart to another until the coherence protocol
has invalidated all older copies from other caches. Of course, microarchitectures may (and highperformance implementations likely will) violate these rules under the covers through speculationor other optimizations, as long as any non-compliant behaviors are not exposed to the programmer.
As a rough guideline for interpreting the PPO rules in RVWMO, we expect the following from thesoftware perspective:• programmers will use PPO rules 1 and 4–8 regularly and actively.
• expert programmers will use PPO rules 9–11 to speed up critical paths of important data
structures.
• even expert programmers will rarely if ever use PPO rules 2–3 and 12–13 directly. These areincluded to facilitate common microarchitectural optimizations (rule 2) and the operational
formal modeling approach (rules 3 and 12–13) described in Section B.3. They also facilitate
the process of porting code from other architectures that have similar rules.
We also expect the following from the hardware perspective:• PPO rules 1 and 3–6 reflect well-understood rules that should pose few surprises to architects.
• PPO rule 2 reflects a natural and common hardware optimization, but one that is very subtle
and hence is worth double checking carefully.
• PPO rule 7 may not be immediately obvious to architects, but it is a standard memory model
requirement• The load value axiom, the atomicity axiom, and PPO rules 8–13 reflect rules that most hardware implementations will enforce naturally, unless they contain extreme optimizations. Of
course, implementations should make sure to double check these rules nevertheless. Hardware
must also ensure that syntactic dependencies are not “optimized away”.
Architectures are free to implement any of the memory model rules as conservatively as they choose.
For example, a hardware implementation may choose to do any or all of the following:

186

Volume I: RISC-V Unprivileged ISA V20191213• interpret all fences as if they were FENCE RW,RW (or FENCE IORW,IORW, if I/O is
involved), regardless of the bits actually set• implement all fences with PW and SR as if they were FENCE RW,RW (orFENCE IORW,IORW, if I/O is involved), as PW with SR is the most expensive of thefour possible main memory ordering components anyway• emulate aq and rl as described in Section A.5• enforcing all same-address load-load ordering, even in the presence of patterns such as “fri-rfi”
and “RSW”• forbid any forwarding of a value from a store in the store buffer to a subsequent AMO or LR
to the same address• forbid any forwarding of a value from an AMO or SC in the store buffer to a subsequent loadto the same address• implement TSO on all memory accesses, and ignore any main memory fences that do notinclude PW and SR ordering (e.g., as Ztso implementations will do)• implement all atomics to be RCsc or even fully-ordered, regardless of annotation

Architectures that implement RVTSO can safely do the following:• Ignore all fences that do not have both PW and SR (unless the fence also orders I/O)
• Ignore all PPO rules except for rules 4 through 7, since the rest are redundant with other
PPO rules under RVTSO assumptions
Other general notes:• Silent stores (i.e., stores that write the same value that already exists at a memory location)
behave like any other store from a memory model point of view. Likewise, AMOs which do
not actually change the value in memory (e.g., an AMOMAX for which the value in rs2 issmaller than the value currently in memory) are still semantically considered store operations.
Microarchitectures that attempt to implement silent stores must take care to ensure that the
memory model is still obeyed, particularly in cases such as RSW (Section A.3.5) which tend
to be incompatible with silent stores.
• Writes may be merged (i.e., two consecutive writes to the same address may be merged) or
subsumed (i.e., the earlier of two back-to-back writes to the same address may be elided) as
long as the resulting behavior does not otherwise violate the memory model semantics.
The question of write subsumption can be understood from the following example:
As written, if the load (d) reads value 1, then (a) must precede (f) in the global memory order:• (a) precedes (c) in the global memory order because of rule 2

Volume I: RISC-V Unprivileged ISA V20191213

187

a: Wx=3

(a)
(b)
(c)

Hart 0li t1, 3
li t2, 1
sw t1,0(s0)fence w, w
sw t2,0(s1)Hart 1
li t3, 2
(d)
(e)
(f)

d: Ry=1
cofence ppo

lw a0,0(s1)sw a0,0(s0)sw t3,0(s0)data pporf

c: Wy=1

e: Wx=1
co ppof: Wx=2

Figure A.19: Write subsumption litmus test, allowed execution.
• (c) precedes (d) in the global memory order because of the Load Value axiom• (d) precedes (e) in the global memory order because of rule 7• (e) precedes (f) in the global memory order because of rule 1
In other words the final value of the memory location whose address is in s0 must be 2 (the value
written by the store (f)) and cannot be 3 (the value written by the store (a)).
A very aggressive microarchitecture might erroneously decide to discard (e), as (f) supersedes it,
and this may in turn lead the microarchitecture to break the now-eliminated dependency between(d) and (f) (and hence also between (a) and (f)). This would violate the memory model rules, andhence it is forbidden. Write subsumption may in other cases be legal, if for example there were nodata dependency between (d) and (e).

A.6.1

Possible Future Extensions

We expect that any or all of the following possible future extensions would be compatible with the
RVWMO memory model:• ‘V’ vector ISA extensions• A transactional memory subset of the ‘T’ ISA extension• ‘J’ JIT extension• Native encodings for load and store opcodes with aq and rl set• Fences limited to certain addresses• Cache writeback/flush/invalidate/etc. instructions

188

Volume I: RISC-V Unprivileged ISA V20191213

(a)
(b)
(c)

Hart 0li t1, 1
lw a0,0(s0)fence rw,rw
sw t1,0(s1)Outcome:Hart 1
li t1, 1(d) lw a1,0(s1)(e) amoswap.w.rl a2,t1,0(s2)(f) ld a3,0(s2)(g) lw a4,4(s2)xor a5,a4,a4
add s0,s0,a5(h) sw a2,0(s0)a0=1, a1=1, a2=0, a3=1, a4=0

Figure A.20: Mixed-size discrepancy (permitted by axiomatic models, forbidden by operationalmodel)

(a)
(b)
(c)

Hart 0li t1, 1
lw a0,0(s0)fence rw,rw
sw t1,0(s1)Outcome:Hart 1
li t1, 1(d) ld a1,0(s1)(e) lw a2,4(s1)xor a3,a2,a2
add s0,s0,a3(f) sw a2,0(s0)a0=0, a1=1, a2=0

Figure A.21: Mixed-size discrepancy (permitted by axiomatic models, forbidden by operationalmodel)

(a)
(b)
(c)

Hart 0li t1, 1
lw a0,0(s0)fence rw,rw
sw t1,0(s1)Outcome:Hart 1
li t1, 1(d) sw t1,4(s1)(e) ld a1,0(s1)(f) lw a2,4(s1)xor a3,a2,a2
add s0,s0,a3(g) sw a2,0(s0)a0=1, a1=0x100000001, a1=1

Figure A.22: Mixed-size discrepancy (permitted by axiomatic models, forbidden by operationalmodel)

A.7

Known Issues

A.7.1

Mixed-size RSW

There is a known discrepancy between the operational and axiomatic specifications within thefamily of mixed-size RSW variants shown in Figures A.20–A.22. To address this, we may choose to
add something like the following new PPO rule: Memory operation a precedes memory operation bin preserved program order (and hence also in the global memory order) if a precedes b in program
order, a and b both access regular main memory (rather than I/O regions), a is a load, b is astore, there is a load m between a and b, there is a byte x that both a and m read, there is no
store between a and m that writes to x, and m precedes b in PPO. In other words, in herd syntax,
we may choose to add “(po-loc & rsw);ppo;[W]” to PPO. Many implementations will alreadyVolume I: RISC-V Unprivileged ISA V20191213

189

enforce this ordering naturally. As such, even though this rule is not official, we recommend that
implementers enforce it nevertheless in order to ensure forwards compatibility with the possible
future addition of this rule to RVWMO.

190

Volume I: RISC-V Unprivileged ISA V20191213

Appendix B

Formal Memory Model Specifications,
Version 0.1
To facilitate formal analysis of RVWMO, this chapter presents a set of formalizations using different
tools and modeling approaches. Any discrepancies are unintended; the expectation is that themodels describe exactly the same sets of legal behaviors.
This appendix should be treated as commentary; all normative material is provided in Chapter 14
and in the rest of the main body of the ISA specification. All currently known discrepancies arelisted in Section A.7. Any other discrepancies are unintentional.

191

192

B.1

Volume I: RISC-V Unprivileged ISA V20191213

Formal Axiomatic Specification in Alloy

We present a formal specification of the RVWMO memory model in Alloy (http://
alloy.mit.edu).
This model is available online at https://github.com/daniellustig/
riscv-memory-model.
The online material also contains some litmus tests and some examples of how Alloy can be used
to model check some of the mappings in Section A.5.
// / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// = RVWMO PPO =// Preserved Program Orderfun ppo : Event - > Event {// same - address orderingpo_loc : > Store+ rdw+ ( AMO + StoreConditional ) <: rfi// explicit synchronization+ ppo_fence+ Acquire <: ^ po : > MemoryEvent+ MemoryEvent <: ^ po : > Release+ RCsc <: ^ po : > RCsc
+ pair// syntactic dependencies+ addrdep+ datadep+ ctrldep : > Store// pipeline dependencies+ ( addrdep + datadep ). rfi+ addrdep .^ po : > Store}// the global memory order respects preserved program orderfact { ppo in ^ gmo }Figure B.1: The RVWMO memory model formalized in Alloy (1/5: PPO)

Volume I: RISC-V Unprivileged ISA V20191213// / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// = RVWMO axioms =// Load Value Axiom
fun candidates [ r : MemoryEvent ] : set MemoryEvent {( r .~^ gmo & Store & same_addr [ r ]) // writes preceding r in gmo+ ( r .^~ po & Store & same_addr [ r ]) // writes preceding r in po}
fun latest_among [ s : set Event ] : Event { s - s .~^ gmo }pred LoadValue {all w : Store | all r : Load |w - > r in rf <= > w = latest_among [ candidates [ r ]]}// Atomicity Axiom
pred Atomicity {all r : Store .~ pair |no x : Store & same_addr [ r ] |x not in same_hart [ r ]and x in r .~ rf .^ gmo
and r . pair in x .^ gmo
}

//
//
//
//
//

starting from the lr ,there is no store x to the same addr
such that x is from a different hart ,x follows ( the store r reads from ) in gmo ,and r follows x in gmo// Progress Axiom implicit : Alloy only considers finite executions
pred RISCV_mm { LoadValue and Atomicity /* and Progress */ }Figure B.2: The RVWMO memory model formalized in Alloy (2/5: Axioms)

193

194

Volume I: RISC-V Unprivileged ISA V20191213// / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// Basic model of memory
sig Hart { // hardware thread
start : one Event}
sig Address {}abstract sig Event {po : lone Event // program order}abstract sig MemoryEvent extends Event {address : one Address ,acquireRCpc : lone MemoryEvent ,acquireRCsc : lone MemoryEvent ,releaseRCpc : lone MemoryEvent ,releaseRCsc : lone MemoryEvent ,addrdep : set MemoryEvent ,ctrldep : set Event ,datadep : set MemoryEvent ,gmo : set MemoryEvent , // global memory orderrf : set MemoryEvent}
sig LoadNormal extends MemoryEvent {} // l { b | h | w | d }sig LoadReserve extends MemoryEvent { // lrpair : lone StoreConditional}sig StoreNormal extends MemoryEvent {}// s { b | h | w | d }// all StoreConditionals in the model are assumed to be successful
sig StoreConditional extends MemoryEvent {} // sc
sig AMO extends MemoryEvent {}// amosig NOP extends Event {}fun Load : Event { LoadNormal + LoadReserve + AMO }fun Store : Event { StoreNormal + StoreConditional + AMO }sig Fence extends Event {pr : lone Fence , // opcode bit
pw : lone Fence , // opcode bit
sr : lone Fence , // opcode bit
sw : lone Fence // opcode bit}
sig FenceTSO extends Fence {}/* Alloy encoding detail : opcode bits are either set ( encoded , e . g . ,* as f . pr in iden ) or unset ( f . pr not in iden ). The bits cannot be used for* anything else */fact { pr + pw + sr + sw in iden }// likewise for ordering annotations
fact { acquireRCpc + acquireRCsc + releaseRCpc + releaseRCsc in iden }// don ’ t try to encode FenceTSO via pr / pw / sr / sw ; just use it as - isfact { no FenceTSO .( pr + pw + sr + sw ) }Figure B.3: The RVWMO memory model formalized in Alloy (3/5: model of memory)

Volume I: RISC-V Unprivileged ISA V20191213

195// / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// = Basic model rules =// Ordering annotation groups
fun Acquire : MemoryEvent { MemoryEvent . acquireRCpc + MemoryEvent . acquireRCsc }fun Release : MemoryEvent { MemoryEvent . releaseRCpc + MemoryEvent . releaseRCsc }fun RCpc : MemoryEvent { MemoryEvent . acquireRCpc + MemoryEvent . releaseRCpc }fun RCsc : MemoryEvent { MemoryEvent . acquireRCsc + MemoryEvent . releaseRCsc }// There is no such thing as store - acquire or load - release , unless it ’ s both
fact { Load & Release in Acquire }fact { Store & Acquire in Release }// FENCE PPO
fun FencePRSR
fun FencePRSW
fun FencePWSR
fun FencePWSW
fun ppo_fence( Load <:+ ( Load <:+ ( Store <:+ ( Store <:+ ( Load <:+ ( Store <:
}

:
:
:
:

Fence
Fence
Fence
Fence

{
{
{
{

Fence .( prFence .( prFence .( pw
Fence .( pw

&
&
&
&

sr )
sw )
sr )
sw )

}
}
}
}

: MemoryEvent - > MemoryEvent {^ po : > FencePRSR ).(^ po : > Load )^ po : > FencePRSW ).(^ po : > Store )^ po : > FencePWSR ).(^ po : > Load )^ po : > FencePWSW ).(^ po : > Store )^ po : > FenceTSO ) .(^ po : > MemoryEvent )^ po : > FenceTSO ) .(^ po : > Store )// auxiliary definitions
fun po_loc : Event - > Event { ^ po & address .~ address }fun same_hart [ e : Event ] : set Event { e + e .^~ po + e .^ po }fun same_addr [ e : Event ] : set Event { e . address .~ address }// initial stores
fun NonInit : set Event { Hart . start .* po }fun Init : set Event { Event - NonInit }fact { Init in StoreNormal }fact { Init - >( MemoryEvent & NonInit ) in ^ gmo }fact { all e : NonInit | one e .*~ po .~ start } // each event is in exactly one hart
fact { all a : Address | one Init & a .~ address } // one init store per address
fact { no Init <: po and no po : > Init }Figure B.4: The RVWMO memory model formalized in Alloy (4/5: Basic model rules)

196

Volume I: RISC-V Unprivileged ISA V20191213// pofact { acyclic [ po ] }// gmofact { total [^ gmo , MemoryEvent ] } // gmo is a total order over all MemoryEvents// rffact { rf .~ rf in iden } // each read returns the value of only one write
fact { rf in Store <: address .~ address : > Load }fun rfi : MemoryEvent - > MemoryEvent { rf & (* po + *~ po ) }// depfact {
fact {
fact {
fact {
fact {
fact {

no StoreNormal <: ( addrdep + ctrldep + datadep ) }addrdep + ctrldep + datadep + pair in ^ po }datadep in datadep : > Store }ctrldep .* po in ctrldep }no pair & (^ po : > ( LoadReserve + StoreConditional )).^ po }StoreConditional in LoadReserve . pair } // assume all SCs succeed// rdw
fun rdw : Event - > Event {( Load <: po_loc : > Load )- (~ rf . rf )- ( po_loc . rfi )}// start with all same_address load - load pairs ,// subtract pairs that read from the same store ,// and subtract out " fri - rfi " patterns// filter out redundant instances and / or visualizations
fact { no gmo & gmo . gmo } // keep the visualization unclutteredfact { all a : Address | some a .~ address }// / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// = Optional : opcode encoding restrictions =// the list of blessed fences
fact { Fence inFence . pr . sr
+ Fence . pw . sw
+ Fence . pr . pw . sw
+ Fence . pr . sr . sw
+ FenceTSO+ Fence . pr . pw . sr . sw}
pred r e s t r i c t _ t o _ c u r r e n t _ e n c o d i n g s {no ( LoadNormal + StoreNormal ) & ( Acquire + Release )}// / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /// = Alloy shortcuts =pred acyclic [ rel : Event - > Event ] { no iden & ^ rel }pred total [ rel : Event - > Event , bag : Event ] {all disj e , e ’: bag | e - >e ’ in rel + ~ relacyclic [ rel ]}Figure B.5: The RVWMO memory model formalized in Alloy (5/5: Auxiliaries)

Volume I: RISC-V Unprivileged ISA V20191213

B.2

197

Formal Axiomatic Specification in Herd

The tool herd takes a memory model and a litmus test as input and simulates the execution of thetest on top of the memory model. Memory models are written in the domain specific language
Cat. This section provides two Cat memory model of RVWMO. The first model, Figure B.7,
follows the global memory order, Chapter 14, definition of RVWMO, as much as is possible for a
Cat model. The second model, Figure B.8, is an equivalent, more efficient, partial order based
RVWMO model.
The simulator herd is part of the diy tool suite — see http://diy.inria.fr for software and documentation. The models and more are available online at http://diy.inria.fr/cats7/riscv/.

198

Volume I: RISC-V Unprivileged ISA V20191213(*************)(* Utilities *)(*************)(* All fence relations *)let fence . r . r = [ R ]; fencerel ( Fence . r . r );[ R ]let fence . r . w = [ R ]; fencerel ( Fence . r . w );[ W ]let fence . r . rw = [ R ]; fencerel ( Fence . r . rw );[ M ]let fence . w . r = [ W ]; fencerel ( Fence . w . r );[ R ]let fence . w . w = [ W ]; fencerel ( Fence . w . w );[ W ]let fence . w . rw = [ W ]; fencerel ( Fence . w . rw );[ M ]let fence . rw . r = [ M ]; fencerel ( Fence . rw . r );[ R ]let fence . rw . w = [ M ]; fencerel ( Fence . rw . w );[ W ]let fence . rw . rw = [ M ]; fencerel ( Fence . rw . rw );[ M ]let fence . tso =let f = fencerel ( Fence . tso ) in([ W ]; f ;[ W ]) | ([ R ]; f ;[ M ])let fence =fence . r . r | fence . r . w | fence . r . rw |fence . w . r | fence . w . w | fence . w . rw |fence . rw . r | fence . rw . w | fence . rw . rw |fence . tso(* Same address , no W to the same address in - between *)let po - loc - no - w = po - loc \ ( po - loc ?;[ W ]; po - loc )(* Read same write *)let rsw = rf ^ -1; rf(* Acquire , or stronger *)let AQ = Acq | AcqRel(* Release or stronger *)and RL = RelAcqRel(* All RCsc *)let RCsc = Acq | Rel | AcqRel(* Amo events are both R and W , relation rmw relates paired lr / sc *)let AMO = R & W
let StCond = range ( rmw )(*************)(* ppo rules *)(*************)(* Overlapping - Address Orderings *)let r1 = [ M ]; po - loc ;[ W ]and r2 = ([ R ]; po - loc - no - w ;[ R ]) \ rsw
and r3 = [ AMO | StCond ]; rfi ;[ R ](* Explicit Synchronization *)and r4 = fence
and r5 = [ AQ ]; po ;[ M ]and r6 = [ M ]; po ;[ RL ]and r7 = [ RCsc ]; po ;[ RCsc ]and r8 = rmw(* Syntactic Dependencies *)and r9 = [ M ]; addr ;[ M ]and r10 = [ M ]; data ;[ W ]and r11 = [ M ]; ctrl ;[ W ](* Pipeline Dependencies *)and r12 = [ R ];( addr | data );[ W ]; rfi ;[ R ]and r13 = [ R ]; addr ;[ M ]; po ;[ W ]let ppo = r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | r11 | r12 | r13

Figure B.6: riscv-defs.cat, a herd definition of preserved program order (1/3)

Volume I: RISC-V Unprivileged ISA V20191213

Total(* Notice that herd has defined its own rf relation *)(* Define ppo *)include " riscv - defs . cat "(********************************)(* Generate global memory order *)(********************************)
let gmo0 = (* precursor : ie build gmo as an total order that include gmo0 *)loc & ( W \ FW ) * FW | # Final write after any write to the same locationppo |# ppo compatiblerfe# includes herd external rf ( optimization )(* Walk over all linear extensions of gmo0 *)with gmo from linearizations ( M \ IW , gmo0 )(* Add initial writes upfront -- convenient for computing rfGMO *)let gmo = gmo | loc & IW * ( M \ IW )(**********)(* Axioms *)(**********)(* Compute rf according to the load value axiom , aka rfGMO *)let WR = loc & ([ W ];( gmo | po );[ R ])let rfGMO = WR \ ( loc &([ W ]; gmo ); WR )(* Check equality of herd rf and of rfGMO *)empty ( rf \ rfGMO )|( rfGMO \ rf ) as RfCons(* Atomicity axiom *)let infloc = ( gmo & loc )^ -1
let inflocext = infloc & ext
let winside = ( infloc ; rmw ; inflocext ) & ( infloc ; rf ; rmw ; inflocext ) & [ W ]empty winside as Atomic

Figure B.7: riscv.cat, a herd version of the RVWMO memory model (2/3)

199

200

Volume I: RISC-V Unprivileged ISA V20191213

Partial(** *************)(* Definitions *)(** *************)(* Define ppo *)include " riscv - defs . cat "(* Compute coherence relation *)include " cos - opt . cat "(**********)(* Axioms *)(**********)(* Sc per location *)acyclic co | rf | fr | po - loc as Coherence(* Main model axiom *)acyclic co | rfe | fr | ppo as Model(* Atomicity axiom *)empty rmw & ( fre ; coe ) as Atomic

Figure B.8: riscv.cat, an alternative herd presentation of the RVWMO memory model (3/3)

Volume I: RISC-V Unprivileged ISA V20191213

B.3

201

An Operational Memory Model

This is an alternative presentation of the RVWMO memory model in operational style. It aims toadmit exactly the same extensional behavior as the axiomatic presentation: for any given program,
admitting an execution if and only if the axiomatic presentation allows it.
The axiomatic presentation is defined as a predicate on complete candidate executions. In contrast,
this operational presentation has an abstract microarchitectural flavor: it is expressed as a statemachine, with states that are an abstract representation of hardware machine states, and with
explicit out-of-order and speculative execution (but abstracting from more implementation-specificmicroarchitectural details such as register renaming, store buffers, cache hierarchies, cache protocols, etc.). As such, it can provide useful intuition. It can also construct executions incrementally,making it possible to interactively and randomly explore the behavior of larger examples, while theaxiomatic model requires complete candidate executions over which the axioms can be checked.
The operational presentation covers mixed-size execution, with potentially overlapping memory
accesses of different power-of-two byte sizes. Misaligned accesses are broken up into single-byte
accesses.
The operational model, together with a fragment of the RISC-V ISA semantics (RV64I and A),
are integrated into the rmem exploration tool (https://github.com/rems-project/rmem). rmem
can explore litmus tests (see A.2) and small ELF binaries exhaustively, pseudo-randomly andinteractively. In rmem, the ISA semantics is expressed explicitly in Sail (see https://github.com/
rems-project/sail for the Sail language, and https://github.com/rems-project/sail-riscv
for the RISC-V ISA model), and the concurrency semantics is expressed in Lem (see https://github.com/rems-project/lem for the Lem language).
rmem has a command-line interface and a web-interface. The web-interface runs entirely on theclient side, and is provided online together with a library of litmus tests: http://www.cl.cam.
ac.uk/~pes20/rmem. The command-line interface is faster than the web-interface, specially inexhaustive mode.
Below is an informal introduction of the model states and transitions. The description of the formal
model starts in the next subsection.
Terminology: In contrast to the axiomatic presentation, here every memory operation is either aload or a store. Hence, AMOs give rise to two distinct memory operations, a load and a store.
When used in conjunction with “instruction”, the terms “load” and “store” refer to instructions
that give rise to such memory operations. As such, both include AMO instructions. The term
“acquire” refers to an instruction (or its memory operation) with the acquire-RCpc or acquireRCsc annotation. The term “release” refers to an instruction (or its memory operation) with therelease-RCpc or release-RCsc annotation.

Model states

A model state consists of a shared memory and a tuple of hart states.
Hart
x 0
y

...

Hart
x n
y

Shared Memory

202

Volume I: RISC-V Unprivileged ISA V20191213

The shared memory state records all the memory store operations that have propagated so far, inthe order they propagated (this can be made more efficient, but for simplicity of the presentation
we keep it this way).
Each hart state consists principally of a tree of instruction instances, some of which have been
finished, and some of which have not. Non-finished instruction instances can be subject to restart,e.g. if they depend on an out-of-order or speculative load that turns out to be unsound.
Conditional branch and indirect jump instructions may have multiple successors in the instruction
tree. When such instruction is finished, any un-taken alternative paths are discarded.
Each instruction instance in the instruction tree has a state that includes an execution state of theintra-instruction semantics (the ISA pseudocode for this instruction). The model uses a formalization of the intra-instruction semantics in Sail. One can think of the execution state of an instruction
as a representation of the pseudocode control state, pseudocode call stack, and local variable values.
An instruction instance state also includes information about the instance’s memory and register
footprints, its register reads and writes, its memory operations, whether it is finished, etc.

Model transitions The model defines, for any model state, the set of allowed transitions, eachof which is a single atomic step to a new abstract machine state. Execution of a single instruction
will typically involve many transitions, and they may be interleaved in operational-model execution
with transitions arising from other instructions. Each transition arises from a single instruction
instance; it will change the state of that instance, and it may depend on or change the rest of
its hart state and the shared memory state, but it does not depend on other hart states, and it
will not change them. The transitions are introduced below and defined in Section B.3.5, with aprecondition and a construction of the post-transition model state for each.
Transitions for all instructions:• Fetch instruction: This transition represents a fetch and decode of a new instruction instance,
as a program order successor of a previously fetched instruction instance (or the initial fetch
address).
The model assumes the instruction memory is fixed; it does not describe the behavior ofself-modifying code. In particular, the Fetch instruction transition does not generate memory
load operations, and the shared memory is not involved in the transition. Instead, the model
depends on an external oracle that provides an opcode when given a memory location.
◦ Register write: This is a write of a register value.
◦ Register read: This is a read of a register value from the most recent program-orderpredecessor instruction instance that writes to that register.
◦ Pseudocode internal step: This covers pseudocode internal computation: arithmetic, function
calls, etc.
◦ Finish instruction: At this point the instruction pseudocode is done, the instruction cannot berestarted, memory accesses cannot be discarded, and all memory effects have taken place. For
conditional branch and indirect jump instructions, any program order successors that wereVolume I: RISC-V Unprivileged ISA V20191213

203

fetched from an address that is not the one that was written to the pc register are discarded,
together with the sub-tree of instruction instances below them.
Transitions specific to load instructions:◦ Initiate memory load operations: At this point the memory footprint of the load instruction
is provisionally known (it could change if earlier instructions are restarted) and its individual
memory load operations can start being satisfied.
• Satisfy memory load operation by forwarding from unpropagated stores: This partially or
entirely satisfies a single memory load operation by forwarding, from program-order-previous
memory store operations.
• Satisfy memory load operation from memory: This entirely satisfies the outstanding slices ofa single memory load operation, from memory.
◦ Complete load operations: At this point all the memory load operations of the instruction
have been entirely satisfied and the instruction pseudocode can continue executing. A load
instruction can be subject to being restarted until the Finish instruction transition. But,
under some conditions, the model might treat a load instruction as non-restartable even
before it is finished (e.g. see Propagate store operation).
Transitions specific to store instructions:◦ Initiate memory store operation footprints: At this point the memory footprint of the store
is provisionally known.
◦ Instantiate memory store operation values: At this point the memory store operations havetheir values and program-order-successor memory load operations can be satisfied by forwarding from them.
◦ Commit store instruction: At this point the store operations are guaranteed to happen (theinstruction can no longer be restarted or discarded), and they can start being propagated tomemory.
• Propagate store operation: This propagates a single memory store operation to memory.
◦ Complete store operations: At this point all the memory store operations of the instruction
have been propagated to memory, and the instruction pseudocode can continue executing.
Transitions specific to sc instructions:• Early sc fail: This causes the sc to fail, either a spontaneous fail or because it is not pairedwith a program-order-previous lr.
• Paired sc: This transition indicates the sc is paired with an lr and might succeed.
• Commit and propagate store operation of an sc: This is an atomic execution of the transitions
Commit store instruction and Propagate store operation, it is enabled only if the stores fromwhich the lr read from have not been overwritten.

204

Volume I: RISC-V Unprivileged ISA V20191213• Late sc fail: This causes the sc to fail, either a spontaneous fail or because the stores fromwhich the lr read from have been overwritten.

Transitions specific to AMO instructions:• Satisfy, commit and propagate operations of an AMO: This is an atomic execution of all thetransitions needed to satisfy the load operation, do the required arithmetic, and propagate
the store operation.
Transitions specific to fence instructions:◦ Commit fence
The transitions labeled ◦ can always be taken eagerly, as soon as their precondition is satisfied,
without excluding other behavior; the • cannot. Although Fetch instruction is marked with a •, it
can be taken eagerly as long as it is not taken infinitely many times.
An instance of a non-AMO load instruction, after being fetched, will typically experience thefollowing transitions in this order:
1. Register read
2. Initiate memory load operations
3. Satisfy memory load operation by forwarding from unpropagated stores and/or Satisfy memory load operation from memory (as many as needed to satisfy all the load operations of theinstance)
4. Complete load operations
5. Register write
6. Finish instruction
Before, between and after the transitions above, any number of Pseudocode internal step transitions
may appear. In addition, a Fetch instruction transition for fetching the instruction in the next
program location will be available until it is taken.
This concludes the informal description of the operational model. The following sections describe
the formal operational model.

B.3.1

Intra-instruction Pseudocode Execution

The intra-instruction semantics for each instruction instance is expressed as a state machine, essentially running the instruction pseudocode. Given a pseudocode execution state, it computes
the next state. Most states identify a pending memory or register operation, requested by thepseudocode, which the memory model has to do. The states are (this is a tagged union; tags insmall-caps):

Volume I: RISC-V Unprivileged ISA V20191213
Load mem(kind, address, size, load continuation)
Early sc fail(res continuation)
Store ea(kind, address, size, next state)Store memv(mem value, store continuation)
Fence(kind, next state)
Read reg(reg name, read continuation)
Write reg(reg name, reg value, next state)
Internal(next state)
Done

205
-

memory load operation
allow sc to fail earlymemory store effective address
memory store value
fence
register readregister write
pseudocode internal step
end of pseudocodeHere:• mem value and reg value are lists of bytes;• address is an integer of XLEN bits;• for load/store, kind identifies whether it is lr/sc, acquire-RCpc/release-RCpc, acquireRCsc/release-RCsc, acquire-release-RCsc;• for fence, kind identifies whether it is a normal or TSO, and (for normal fences) the predecessor
and successor ordering bits;• reg name identifies a register and a slice thereof (start and end bit indices); and• the continuations describe how the instruction instance will continue for each valuethat might be provided by the surrounding memory model (the load continuation andread continuation take the value loaded from memory and read from the previous register
write, the store continuation takes false for an sc that failed and true in all other cases, andres continuation takes false if the sc fails and true otherwise).
For example, given the load instruction lw x1,0(x2), an execution will typically go as follows.
The initial execution state will be computed from the pseudocode for the given opcode. Thiscan be expected to be Read reg(x2, read continuation). Feeding the most recently written
value of register x2 (the instruction semantics will be blocked if necessary until the registervalue is available), say 0x4000, to read continuation returns Load mem(plain load, 0x4000,
4, load continuation). Feeding the 4-byte value loaded from memory location 0x4000, say 0x42,
to load continuation returns Write reg(x1, 0x42, Done). Many Internal(next state) states
may appear before and between the states above.

Notice that writing to memory is split into two steps, Store ea and Store memv: the first one
makes the memory footprint of the store provisionally known, and the second one adds the value tobe stored. We ensure these are paired in the pseudocode (Store ea followed by Store memv),
but there may be other steps between them.
It is observable that the Store ea can occur before the value to be stored is determined. For
example, for the litmus test LB+fence.r.rw+data-po to be allowed by the operational model (asit is by RVWMO), the first store in Hart 1 has to take the Store ea step before its value
is determined, so that the second store can see it is to a non-overlapping memory footprint,
allowing the second store to be committed out of order without violating coherence.

The pseudocode of each instruction performs at most one store or one load, except for AMOs
that perform exactly one load and one store. Those memory accesses are then split apart into
the architecturally atomic units by the hart semantics (see Initiate memory load operations andInitiate memory store operation footprints below).

206

Volume I: RISC-V Unprivileged ISA V20191213

Informally, each bit of a register read should be satisfied from a register write by the most recent(in program order) instruction instance that can write that bit (or from the hart’s initial register
state if there is no such write). Hence, it is essential to know the register write footprint of each
instruction instance, which we calculate when the instruction instance is created (see the actionof Fetch instruction below). We ensure in the pseudocode that each instruction does at most one
register write to each register bit, and also that it does not try to read a register value it just wrote.
Data-flow dependencies (address and data) in the model emerge from the fact that each register
read has to wait for the appropriate register write to be executed (as described above).

B.3.2

Instruction Instance State

Each instruction instance i has a state comprising:• program loc, the memory address from which the instruction was fetched;• instruction kind, identifying whether this is a load, store, AMO, fence, branch/jump or a‘simple’ instruction (this also includes a kind similar to the one described for the pseudocode
execution states);• src regs, the set of source reg names (including system registers), as statically determinedfrom the pseudocode of the instruction;• dst regs, the destination reg names (including system registers), as statically determined fromthe pseudocode of the instruction;• pseudocode state (or sometimes just ‘state’ for short), one of (this is a tagged union; tags insmall-caps):
Plain(isa state)
Pending mem loads(load continuation)
Pending mem stores(store continuation)- ready to make a pseudocode transition- requesting memory load operation(s)- requesting memory store operation(s)• reg reads, the register reads the instance has performed, including, for each one, the register
write slices it read from;• reg writes, the register writes the instance has performed;• mem loads, a set of memory load operations, and for each one the as-yet-unsatisfied slices(the byte indices that have not been satisfied yet), and, for the satisfied slices, the store slices(each consisting of a memory store operation and subset of its byte indices) that satisfied it.
• mem stores, a set of memory store operations, and for each one a flag that indicates whether
it has been propagated (passed to the shared memory) or not.
• information recording whether the instance is committed, finished, etc.
Each memory load operation includes a memory footprint (address and size). Each memory store
operations includes a memory footprint, and, when available, a value.

Volume I: RISC-V Unprivileged ISA V20191213

207

A load instruction instance with a non-empty mem loads, for which all the load operations are
satisfied (i.e. there are no unsatisfied load slices) is said to be entirely satisfied.
Informally, an instruction instance is said to have fully determined data if the load (and sc) instructions feeding its source registers are finished. Similarly, it is said to have a fully determinedmemory footprint if the load (and sc) instructions feeding its memory operation address registerare finished. Formally, we first define the notion of fully determined register write: a register write
w from reg writes of instruction instance i is said to be fully determined if one of the following
conditions hold:
1. i is finished; or
2. the value written by w is not affected by a memory operation that i has made (i.e. a value
loaded from memory or the result of sc), and, for every register read that i has made, that
affects w, the register write from which i read is fully determined (or i read from the initial
register state).
Now, an instruction instance i is said to have fully determined data if for every register read r fromreg reads, the register writes that r reads from are fully determined. An instruction instance i is
said to have a fully determined memory footprint if for every register read r from reg reads that
feeds into i’s memory operation address, the register writes that r reads from are fully determined.

The rmem tool records, for every register write, the set of register writes from other instructions
that have been read by this instruction at the point of performing the write. By carefully arranging
the pseudocode of the instructions covered by the tool we were able to make it so that this is exactly
the set of register writes on which the write depends on.

B.3.3

Hart StateThe model state of a single hart comprises:• hart id, a unique identifier of the hart;• initial register state, the initial register value for each register;• initial fetch address, the initial instruction fetch address;• instruction tree, a tree of the instruction instances that have been fetched (and not discarded),in program order.

B.3.4

Shared Memory StateThe model state of the shared memory comprises a list of memory store operations, in the order
they propagated to the shared memory.

208

Volume I: RISC-V Unprivileged ISA V20191213

When a store operation is propagated to the shared memory it is simply added to the end of thelist. When a load operation is satisfied from memory, for each byte of the load operation, the mostrecent corresponding store slice is returned.
For most purposes, it is simpler to think of the shared memory as an array, i.e., a map frommemory locations to memory store operation slices, where each memory location is mapped
to a one-byte slice of the most recent memory store operation to that location. However, thisabstraction is not detailed enough to properly handle the sc instruction. The RVWMO Atomicity
Axiom allows store operations from the same hart as the sc to intervene between the store
operation of the sc and the store operations the paired lr read from. To allow such store
operations to intervene, and forbid others, the array abstraction must be extended to record
more information. Here, we use a list as it is very simple, but a more efficient and scalable
implementations should probably use something better.

B.3.5

Transitions

Each of the paragraphs below describes a single kind of system transition. The description starts
with a condition over the current system state. The transition can be taken in the current state
only if the condition is satisfied. The condition is followed by an action that is applied to that state
when the transition is taken, in order to generate the new system state.

Fetch instruction
from address loc if:

A possible program-order-successor of instruction instance i can be fetched

1. it has not already been fetched, i.e., none of the immediate successors of i in the hart’s
instruction tree are from loc; and2. if i’s pseudocode has already written an address to pc, then loc must be that address, otherwise
loc is:• for a conditional branch, the successor address or the branch target address;• for a (direct) jump and link instruction (jal), the target address;• for an indirect jump instruction (jalr), any address; and• for any other instruction, i.program loc + 4.
Action: construct a freshly initialized instruction instance i′ for the instruction in the program
memory at loc, with state Plain(isa state), computed from the instruction pseudocode, including
the static information available from the pseudocode such as its instruction kind, src regs, anddst regs, and add i′ to the hart’s instruction tree as a successor of i.
The possible next fetch addresses (loc) are available immediately after fetching i and the model
does not need to wait for the pseudocode to write to pc; this allows out-of-order execution, andspeculation past conditional branches and jumps. For most instructions these addresses areeasily obtained from the instruction pseudocode. The only exception to that is the indirect jump
instruction (jalr), where the address depends on the value held in a register. In principle themathematical model should allow speculation to arbitrary addresses here. The exhaustive search

Volume I: RISC-V Unprivileged ISA V20191213

209

in the rmem tool handles this by running the exhaustive search multiple times with a growing setof possible next fetch addresses for each indirect jump. The initial search uses empty sets, hence
there is no fetch after indirect jump instruction until the pseudocode of the instruction writes
to pc, and then we use that value for fetching the next instruction. Before starting the next
iteration of exhaustive search, we collect for each indirect jump (grouped by code location) the
set of values it wrote to pc in all the executions in the previous search iteration, and use thatas possible next fetch addresses of the instruction. This process terminates when no new fetch
addresses are detected.

Initiate memory load operations An instruction instance i in state Plain(Load mem(kind,address, size, load continuation)) can always initiate the corresponding memory load operations.
Action:1. Construct the appropriate memory load operations mlos:• if address is aligned to size then mlos is a single memory load operation of size bytes
from address;• otherwise, mlos is a set of size memory load operations, each of one byte, from theaddresses address . . . address + size − 1.
2. set mem loads of i to mlos; and3. update the state of i to Pending mem loads(load continuation).
In Section 14.1 it is said that misaligned memory accesses may be decomposed at any granularity.
Here we decompose them to one-byte accesses as this granularity subsumes all others.

Satisfy memory load operation by forwarding from unpropagated stores For a nonAMO load instruction instance i in state Pending mem loads(load continuation), and a memory
load operation mlo in i.mem loads that has unsatisfied slices, the memory load operation can bepartially or entirely satisfied by forwarding from unpropagated memory store operations by store
instruction instances that are program-order-before i if:
1. all program-order-previous fence instructions with .sr and .pw set are finished;
2. for every program-order-previous fence instruction, f , with .sr and .pr set, and .pw not
set, if f is not finished then all load instructions that are program-order-before f are entirely
satisfied;
3. for every program-order-previous fence.tso instruction, f , that is not finished, all load
instructions that are program-order-before f are entirely satisfied;
4. if i is a load-acquire-RCsc, all program-order-previous store-releases-RCsc are finished;
5. if i is a load-acquire-release, all program-order-previous instructions are finished;
6. all non-finished program-order-previous load-acquire instructions are entirely satisfied; and7. all program-order-previous store-acquire-release instructions are finished;210

Volume I: RISC-V Unprivileged ISA V20191213

Let msoss be the set of all unpropagated memory store operation slices from non-sc store instruction instances that are program-order-before i and have already calculated the value to be
stored, that overlap with the unsatisfied slices of mlo, and which are not superseded by intervening
store operations or store operations that are read from by an intervening load. The last condition
requires, for each memory store operation slice msos in msoss from instruction i′ :• that there is no store instruction program-order-between i and i′ with a memory store operation overlapping msos; and• that there is no load instruction program-order-between i and i′ that was satisfied from an
overlapping memory store operation slice from a different hart.
Action:
1. update i.mem loads to indicate that mlo was satisfied by msoss; and2. restart any speculative instructions which have violated coherence as a result of this, i.e., forevery non-finished instruction i′ that is a program-order-successor of i, and every memory
load operation mlo′ of i′ that was satisfied from msoss′ , if there exists a memory store
operation slice msos′ in msoss′ , and an overlapping memory store operation slice from adifferent memory store operation in msoss, and msos′ is not from an instruction that is a
program-order-successor of i, restart i′ and its restart-dependents.
Where, the restart-dependents of instruction j are:• program-order-successors of j that have data-flow dependency on a register write of j;• program-order-successors of j that have a memory load operation that reads from a memory
store operation of j (by forwarding);• if j is a load-acquire, all the program-order-successors of j;• if j is a load, for every fence, f , with .sr and .pr set, and .pw not set, that is a programorder-successor of j, all the load instructions that are program-order-successors of f ;• if j is a load, for every fence.tso, f , that is a program-order-successor of j, all the load
instructions that are program-order-successors of f ; and• (recursively) all the restart-dependents of all the instruction instances above.
Forwarding memory store operations to a memory load might satisfy only some slices of theload, leaving other slices unsatisfied.
A program-order-previous store operation that was not available when taking the transition
above might make msoss provisionally unsound (violating coherence) when it becomes available.
That store will prevent the load from being finished (see Finish instruction), and will cause it torestart when that store operation is propagated (see Propagate store operation).
A consequence of the transition condition above is that store-release-RCsc memory store operations cannot be forwarded to load-acquire-RCsc instructions: msoss does not include memory
store operations from finished stores (as those must be propagated memory store operations), andthe condition above requires all program-order-previous store-releases-RCsc to be finished when
the load is acquire-RCsc.

Satisfy memory load operation from memory For an instruction instance i of a non-AMO
load instruction or an AMO instruction in the context of the “Satisfy, commit and propagate operations of an AMO” transition, any memory load operation mlo in i.mem loads that has unsatisfied

Volume I: RISC-V Unprivileged ISA V20191213

211

slices, can be satisfied from memory if all the conditions of Satisfy memory load operation by forwarding from unpropagated stores are satisfied. Action: let msoss be the memory store operation
slices from memory covering the unsatisfied slices of mlo, and apply the action of Satisfy memory
load operation by forwarding from unpropagated stores.
Note that Satisfy memory load operation by forwarding from unpropagated stores might leavesome slices of the memory load operation unsatisfied, those will have to be satisfied by taking thetransition again, or taking Satisfy memory load operation from memory. Satisfy memory load
operation from memory, on the other hand, will always satisfy all the unsatisfied slices of thememory load operation.

Complete
load
operations A load instruction instance i in state Pending mem loads(load continuation) can be completed (not to be confused with finished) if
all the memory load operations i.mem loads are entirely satisfied (i.e. there are no unsatisfied
slices). Action: update the state of i to Plain(load continuation(mem value)), where mem value
is assembled from all the memory store operation slices that satisfied i.mem loads.

Early sc fail An sc instruction instance i in state Plain(Early sc fail(res continuation)) canalways be made to fail. Action: update the state of i to Plain(res continuation(false)).

Paired sc An sc instruction instance i in state Plain(Early sc fail(res continuation)) cancontinue its (potentially successful) execution if i is paired with an lr. Action: update the state ofi to Plain(res continuation(true)).

Initiate memory store operation footprints An instruction instance i in state
Plain(Store ea(kind, address, size, next state)) can always announce its pending memory store
operation footprint. Action:
1. construct the appropriate memory store operations msos (without the store value):• if address is aligned to size then msos is a single memory store operation of size bytes
to address;• otherwise, msos is a set of size memory store operations, each of one-byte size, to theaddresses address . . . address + size − 1.
2. set i.mem stores to msos; and3. update the state of i to Plain(next state).

Note that after taking the transition above the memory store operations do not yet have theirvalues. The importance of splitting this transition from the transition below is that it allows otherprogram-order-successor store instructions to observe the memory footprint of this instruction,and if they don’t overlap, propagate out of order as early as possible (i.e. before the data registervalue becomes available).

212

Volume I: RISC-V Unprivileged ISA V20191213

Instantiate memory store operation values An instruction instance i in state
Plain(Store memv(mem value, store continuation)) can always instantiate the values of thememory store operations i.mem stores. Action:
1. split mem value between the memory store operations i.mem stores; and2. update the state of i to Pending mem stores(store continuation).
Commit store instruction An uncommitted instruction instance i of a non-sc store instruction
or an sc instruction in the context of the “Commit and propagate store operation of an sc” transition, in state Pending mem stores(store continuation), can be committed (not to be confusedwith propagated) if:
1. i has fully determined data;
2. all program-order-previous conditional branch and indirect jump instructions are finished;
3. all program-order-previous fence instructions with .sw set are finished;
4. all program-order-previous fence.tso instructions are finished;
5. all program-order-previous load-acquire instructions are finished;
6. all program-order-previous store-acquire-release instructions are finished;
7. if i is a store-release, all program-order-previous instructions are finished;
8. all program-order-previous memory access instructions have a fully determined memory footprint;
9. all program-order-previous store instructions, except for sc that failed, have initiated and sohave non-empty mem stores; and10. all program-order-previous load instructions have initiated and so have non-empty mem loads.
Action: record that i is committed.
Notice that if condition 8 is satisfied the conditions 9 and 10 are also satisfied, or will be satisfied after taking some eager transitions. Hence, requiring them does not strengthen the model.
By requiring them, we guarantee that previous memory access instructions have taken enoughtransitions to make their memory operations visible for the condition check of Propagate store
operation, which is the next transition the instruction will take, making that condition simpler.

Propagate store operation For a committed instruction instance i in state Pending mem stores(store continuation), and an unpropagated memory store operation mso ini.mem stores, mso can be propagated if:
1. all memory store operations of program-order-previous store instructions that overlap withmso have already propagated;

Volume I: RISC-V Unprivileged ISA V20191213

213

2. all memory load operations of program-order-previous load instructions that overlap withmso have already been satisfied, and (the load instructions) are non-restartable (see definition
below); and3. all memory load operations that were satisfied by forwarding mso are entirely satisfied.
Where a non-finished instruction instance j is non-restartable if:
1. there does not exist a store instruction s and an unpropagated memory store operation mso
of s such that applying the action of the “Propagate store operation” transition to mso will
result in the restart of j; and2. there does not exist a non-finished load instruction l and a memory load operation mlo of
l such that applying the action of the “Satisfy memory load operation by forwarding from
unpropagated stores”/“Satisfy memory load operation from memory” transition (even if mlo
is already satisfied) to mlo will result in the restart of j.
Action:
1. update the shared memory state with mso;
2. update i.mem stores to indicate that mso was propagated; and3. restart any speculative instructions which have violated coherence as a result of this, i.e.,
for every non-finished instruction i′ program-order-after i and every memory load operation
mlo′ of i′ that was satisfied from msoss′ , if there exists a memory store operation slice msos′
in msoss′ that overlaps with mso and is not from mso, and msos′ is not from a programorder-successor of i, restart i′ and its restart-dependents (see Satisfy memory load operation
by forwarding from unpropagated stores).

Commit and propagate store operation of an sc An uncommitted sc instruction instancei, from hart h, in state Pending mem stores(store continuation), with a paired lr i′ that has
been satisfied by some store slices msoss, can be committed and propagated at the same time if:
1. i′ is finished;
2. every memory store operation that has been forwarded to i′ is propagated;
3. the conditions of Commit store instruction is satisfied;
4. the conditions of Propagate store operation is satisfied (notice that an sc instruction can only
have one memory store operation); and5. for every store slice msos from msoss, msos has not been overwritten, in the shared memory,by a store that is from a hart that is not h, at any point since msos was propagated tomemory.
Action:214

Volume I: RISC-V Unprivileged ISA V20191213

1. apply the actions of Commit store instruction; and2. apply the action of Propagate store operation.

Late sc fail An sc instruction instance i in state Pending mem stores(store continuation),that has not propagated its memory store operation, can always be made to fail. Action:
1. clear i.mem stores; and2. update the state of i to Plain(store continuation(false)).
For efficiency, the rmem tool allows this transition only when it is not possible to take the Commit
and propagate store operation of an sc transition. This does not affect the set of allowed final
states, but when explored interactively, if the sc should fail one should use the Early sc failtransition instead of waiting for this transition.

Complete store operations A store instruction instance i in state Pending mem stores(store continuation), for which all the memory store operations in i.mem stores
have been propagated, can always be completed (not to be confused with finished). Action: update
the state of i to Plain(store continuation(true)).
Satisfy, commit and propagate operations of an AMO An AMO instruction instance i instate Pending mem loads(load continuation) can perform its memory access if it is possible toperform the following sequence of transitions with no intervening transitions:
1. Satisfy memory load operation from memory
2. Complete load operations
3. Pseudocode internal step (zero or more times)
4. Instantiate memory store operation values
5. Commit store instruction
6. Propagate store operation
7. Complete store operations
and in addition, the condition of Finish instruction, with the exception of not requiring i to be instate Plain(Done), holds after those transitions. Action: perform the above sequence of transitions (this does not include Finish instruction), one after the other, with no intervening transitions.
Notice that program-order-previous stores cannot be forwarded to the load of an AMO. This issimply because the sequence of transitions above does not include the forwarding transition. But
even if it did include it, the sequence will fail when trying to do the Propagate store operationtransition, as this transition requires all program-order-previous store operations to overlappingVolume I: RISC-V Unprivileged ISA V20191213

215

memory footprints to be propagated, and forwarding requires the store operation to be unpropagated.
In addition, the store of an AMO cannot be forwarded to a program-order-successor load.
Before taking the transition above, the store operation of the AMO does not have its value andtherefore cannot be forwarded; after taking the transition above the store operation is propagated
and therefore cannot be forwarded.

Commit fence
committed if:

A fence instruction instance i in state Plain(Fence(kind, next state)) can be

1. if i is a normal fence and it has .pr set, all program-order-previous load instructions are
finished;
2. if i is a normal fence and it has .pw set, all program-order-previous store instructions are
finished; and3. if i is a fence.tso, all program-order-previous load and store instructions are finished.
Action:
1. record that i is committed; and2. update the state of i to Plain(next state).
Register read An instruction instance i in state Plain(Read reg(reg name, read cont)) can
do a register read of reg name if every instruction instance that it needs to read from has alreadyperformed the expected reg name register write.
Let read sources include, for each bit of reg name, the write to that bit by the most recent (inprogram order) instruction instance that can write to that bit, if any. If there is no such instruction,
the source is the initial register value from initial register state. Let reg value be the value assembled
from read sources. Action:
1. add reg name to i.reg reads with read sources and reg value; and2. update the state of i to Plain(read cont(reg value)).
Register write An instruction instance i in state Plain(Write reg(reg name, reg value,
next state)) can always do a reg name register write. Action:
1. add reg name to i.reg writes with deps and reg value; and2. update the state of i to Plain(next state).
where deps is a pair of the set of all read sources from i.reg reads, and a flag that is true iff i is aload instruction instance that has already been entirely satisfied.

216

Volume I: RISC-V Unprivileged ISA V20191213

Pseudocode internal step An instruction instance i in state Plain(Internal(next state)) canalways do that pseudocode-internal step. Action: update the state of i to Plain(next state).

Finish instruction A non-finished instruction instance i in state Plain(Done) can be finishedif:
1. if i is a load instruction:(a) all program-order-previous load-acquire instructions are finished;(b) all program-order-previous fence instructions with .sr set are finished;(c) for every program-order-previous fence.tso instruction, f , that is not finished, all load
instructions that are program-order-before f are finished; and(d) it is guaranteed that the values read by the memory load operations of i will not cause
coherence violations, i.e., for any program-order-previous instruction instance i′ , let cfp
be the combined footprint of propagated memory store operations from store instructions
program-order-between i and i′ , and fixed memory store operations that were forwarded
to i from store instructions program-order-between i and i′ including i′ , and let cfp be
the complement of cfp in the memory footprint of i. If cfp is not empty:
i. i′ has a fully determined memory footprint;
ii. i′ has no unpropagated memory store operations that overlap with cfp; andiii. if i′ is a load with a memory footprint that overlaps with cfp, then all the memory
load operations of i′ that overlap with cfp are satisfied and i′ is non-restartable (seethe Propagate store operation transition for how to determined if an instruction is
non-restartable).
Here, a memory store operation is called fixed if the store instruction has fully determineddata.
2. i has a fully determined data; and3. if i is not a fence, all program-order-previous conditional branch and indirect jump instructions
are finished.
Action:
1. if i is a conditional branch or indirect jump instruction, discard any untaken paths of execution, i.e., remove all instruction instances that are not reachable by the branch/jump taken
in instruction tree; and2. record the instruction as finished, i.e., set finished to true.

B.3.6

Limitations• The model covers user-level RV64I and RV64A. In particular, it does not support the misaligned atomics extension “Zam” or the total store ordering extension “Ztso”. It should beVolume I: RISC-V Unprivileged ISA V20191213

217

trivial to adapt the model to RV32I/A and to the G, Q and C extensions, but we have nevertried it. This will involve, mostly, writing Sail code for the instructions, with minimal, if any,changes to the concurrency model.
• The model covers only normal memory accesses (it does not handle I/O accesses).
• The model does not cover TLB-related effects.
• The model assumes the instruction memory is fixed. In particular, the Fetch instruction
transition does not generate memory load operations, and the shared memory is not involvedin the transition. Instead, the model depends on an external oracle that provides an opcode
when given a memory location.
• The model does not cover exceptions, traps and interrupts.

218

Volume I: RISC-V Unprivileged ISA V20191213

Bibliography[1] RISC-V ELF psABI Specification. https://github.com/riscv/riscv-elf-psabi-doc/.
[2] IEEE standard for a 32-bit microprocessor. IEEE Std. 1754-1994, 1994.
[3] G. M. Amdahl, G. A. Blaauw, and Jr. F. P. Brooks. Architecture of the IBM System/360.
IBM Journal of R. & D., 8(2), 1964.
[4] Werner Buchholz, editor. Planning a computer system: Project Stretch. McGraw-Hill Book
Company, 1962.
[5] Kourosh Gharachorloo, Daniel Lenoski, James Laudon, Phillip Gibbons, Anoop Gupta, andJohn Hennessy. Memory consistency and event ordering in scalable shared-memory multiprocessors. In In Proceedings of the 17th Annual International Symposium on Computer Architecture, pages 15–26, 1990.
[6] Timothy H. Heil and James E. Smith. Selective dual path execution. Technical report, University of Wisconsin - Madison, November 1996.
[7] ANSI/IEEE Std 754-2008, IEEE standard for floating-point arithmetic, 2008.
[8] Manolis G.H. Katevenis, Robert W. Sherburne, Jr., David A. Patterson, and Carlo H. Séquin.
The RISC II micro-architecture. In Proceedings VLSI 83 Conference, August 1983.
[9] Hyesoon Kim, Onur Mutlu, Jared Stark, and Yale N. Patt. Wish branches: Combining conditional branching and predication for adaptive predicated execution. In Proceedings of the 38th
annual IEEE/ACM International Symposium on Microarchitecture, MICRO 38, pages 43–54,
2005.
[10] A. Klauser, T. Austin, D. Grunwald, and B. Calder. Dynamic hammock predication for nonpredicated instruction set architectures. In Proceedings of the 1998 International Conference
on Parallel Architectures and Compilation Techniques, PACT ’98, Washington, DC, USA,
1998.
[11] David D. Lee, Shing I. Kong, Mark D. Hill, George S. Taylor, David A. Hodges, Randy H.
Katz, and David A. Patterson. A VLSI chip set for a multiprocessor workstation–Part I: An
RISC microprocessor with coprocessor interface and support for symbolic processing. IEEE
JSSC, 24(6):1688–1698, December 1989.
[12] OpenCores. OpenRISC 1000 architecture manual, architecture version 1.0, December 2012.

219

220

Volume I: RISC-V Unprivileged ISA V20191213[13] Heidi Pan, Benjamin Hindman, and Krste Asanović. Lithe: Enabling efficient composition ofparallel libraries. In Proceedings of the 1st USENIX Workshop on Hot Topics in Parallelism(HotPar ’09), Berkeley, CA, March 2009.
[14] Heidi Pan, Benjamin Hindman, and Krste Asanović. Composing parallel software efficiently
with Lithe. In 31st Conference on Programming Language Design and Implementation,
Toronto, Canada, June 2010.
[15] David A. Patterson and Carlo H. Séquin. RISC I: A reduced instruction set VLSI computer.
In ISCA, pages 443–458, 1981.
[16] Ravi Rajwar and James R. Goodman. Speculative lock elision: enabling highly concurrent multithreaded execution. In Proceedings of the 34th annual ACM/IEEE International Symposiumon Microarchitecture, MICRO 34, pages 294–305. IEEE Computer Society, 2001.
[17] Balaram Sinharoy, R. Kalla, W. J. Starke, H. Q. Le, R. Cargnoni, J. A. Van Norstrand,
B. J. Ronchetti, J. Stuecheli, J. Leenstra, G. L. Guthrie, D. Q. Nguyen, B. Blaner, C. F.
Marino, E. Retter, and P. Williams. IBM POWER7 multicore server processor. IBM Journalof Research and Development, 55(3):1–1, 2011.
[18] James E. Thornton. Parallel operation in the Control Data 6600. In Proceedings of the October
27-29, 1964, Fall Joint Computer Conference, Part II: Very High Speed Computer Systems,
AFIPS ’64 (Fall, part II), pages 33–40, 1965.
[19] Marc Tremblay, Jeffrey Chan, Shailender Chaudhry, Andrew W. Conigliaro, and Shing Sheung
Tse. The MAJC architecture: A synthesis of parallelism and scalability. IEEE Micro, 20(6):12–
25, 2000.
[20] J. Tseng and K. Asanović. Energy-efficient register access. In Proc. of the 13th Symposium on
Integrated Circuits and Systems Design, pages 377–384, Manaus, Brazil, September 2000.
[21] David Ungar, Ricki Blau, Peter Foley, Dain Samples, and David Patterson. Architecture of
SOAR: Smalltalk on a RISC. In ISCA, pages 188–197, Ann Arbor, MI, 1984.
[22] Andrew Waterman. Improving Energy Efficiency and Reducing Code Size with RISC-V Compressed. Master’s thesis, University of California, Berkeley, 2011.
[23] Andrew Waterman. Design of the RISC-V Instruction Set Architecture. PhD thesis, Universityof California, Berkeley, 2016.
[24] Andrew Waterman, Yunsup Lee, David A. Patterson, and Krste Asanović. The RISC-V
instruction set manual, Volume I: Base user-level ISA. Technical Report UCB/EECS-2011-62,
EECS Department, University of California, Berkeley, May 2011.
[25] Andrew Waterman, Yunsup Lee, David A. Patterson, and Krste Asanović. The RISC-V instruction set manual, Volume I: Base user-level ISA version 2.0. Technical Report UCB/EECS2014-54, EECS Department, University of California, Berkeley, May 2014.