aboutsummaryrefslogtreecommitdiff
path: root/src/rvwmo.adoc
blob: d719a4ea47ae4bfe56721150d7a436168c8b30a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
[[memorymodel]]
== RVWMO Memory Consistency Model, Version 2.0

This chapter defines the RISC-V memory consistency model. A memory
consistency model is a set of rules specifying the values that can be
returned by loads of memory. RISC-V uses a memory model called "RVWMO"
(RISC-V Weak Memory Ordering) which is designed to provide flexibility
for architects to build high-performance scalable designs while
simultaneously supporting a tractable programming model.
(((design, high performance)))
(((design, scalable)))

Under RVWMO, code running on a single hart appears to execute in order
from the perspective of 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 for this purpose, described
in <<fence>>, while the atomics extension "A" additionally defines load-reserved/store-conditional and atomic read-modify-write instructions.
(((atomics, misaligned)))

The standard ISA extension for total store ordering "Ztso" (<<ztso>>) augments
RVWMO with additional rules specific to those extensions.

The appendices to this specification provide both axiomatic and
operational formalizations of the memory consistency model as well as
additional explanatory material.
(((FENCE)))
(((SFENCE)))

[NOTE]
====
This chapter defines the memory model for regular main memory
operations. The interaction of 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 future
revision of this specification. The RV128 base ISA and future ISA
extensions such as the V vector and J JIT extensions will need
to be incorporated into a future 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 the
best of our current abilities, but they are subject to revision should
new issues be uncovered.
====

[[rvwmo]]
=== Definition of the RVWMO Memory Model

The RVWMO memory model is defined in terms of the _global memory order_,
a total ordering of the memory 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.
(((RVWMO)))

The global memory order is defined over the primitive load and store
operations generated by memory 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).

[[rvwmo-primitives]]
==== Memory Model Primitives

The _program order_ over memory operations reflects the order in which
the instructions that generate each load and store are logically laid
out in that hart's dynamic instruction stream; i.e., the order in 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.
(((operations, memory)))

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 not give rise to any memory
operations. Second, FLD and FSD instructions may each give rise to
multiple memory operations if XLEN<64, as stated in
<<fld_fsd>> and clarified below. An aligned AMO
gives rise to a single memory operation that is both a load operation
and a store operation simultaneously.

[NOTE]
====
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 for these 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 are ordered 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 misaligned atomicity
granule PMA, then AMOs within an atomicity granule are not decomposed, nor are
loads and stores defined in the base ISAs, nor are loads and stores of no more
than XLEN bits defined in the F, D, and Q extensions.
(((decomposition)))

[NOTE]
====
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.
====

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
<<sec:lrsc>>.

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 "release-RCsc" 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 a
release-RCsc annotation. An "RCpc annotation" refers to an
acquire-RCpc annotation or a release-RCpc annotation. An _RCsc
annotation_ refers to an acquire-RCsc annotation or a release-RCsc
annotation.

[NOTE]
====
In the memory model literature, the term "RCpc" stands for release
consistency with processor-consistent synchronization operations, and
the term "RCsc" stands for release consistency with sequentially
consistent synchronization operations.

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 <<ppo, Preserved Program Order>> rules 5-7.

"RCpc" annotations are currently only used when implicitly assigned to
every memory access per the standard extension "Ztso"
(<<ztso>>). 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.
====

[[mem-dependencies]]
==== 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 are tracked through CSRs is
specific to each CSR and is defined in
<<csr-granularity>>.

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 their
destination registers. This section provides a general definition of all
of these terms; however, <<source-dest-regs>> 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_
* _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 <<source-dest-regs>>
* _r_ is a CSR that aliases with another source register for
_i_

Memory instructions also further specify which source registers are
_address source registers_ and which are _data source registers_.

In general, a register _r_ other than `x0` is a _destination
register_ for an instruction _i_ if any of the following
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 <<source-dest-regs>>
* _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 <<source-dest-regs>>.

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:
. _j_ has a syntactic dependency on _m_ via
destination register _q_ and source register _r_
. _m_ has a syntactic dependency on _i_ via
destination register _s_ and source register _p_
. _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 the instructions 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 _r_

_b_ 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 _r_

_b_ has a _syntactic control dependency_ on _a_
if there is an instruction _m_ program-ordered between
_i_ and _j_ such that _m_ is a
branch or indirect jump and _m_ has a syntactic dependency
on _i_.

[NOTE]
====
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 instruction that precedes it in
program order.
====

==== Preserved Program Order
[[ppo]]
The global memory order for any given execution of a program respects
some but not all of each hart’s program order. The subset of program
order that must be respected by the global memory order 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_ and _b_ both access regular main memory
(rather than I/O regions), and any of the following hold:

[[overlapping-ordering]]
* Overlapping-Address Orderings:
. _b_ is a store, and
_a_ and _b_ access overlapping memory addresses
. _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
. _a_ is
generated by an AMO or SC instruction, _b_ is a load, and
_b_ returns a value written by _a_
* Explicit Synchronization
[start=4]
. There is a FENCE instruction that
orders _a_ before _b_
. _a_ has an acquire
annotation
. _b_ has a release annotation
. _a_ and _b_ both have
RCsc annotations
. _a_ is paired with
_b_
* Syntactic Dependencies
[start=9]
. _b_ has a syntactic address
dependency on _a_
. _b_ has a syntactic data
dependency on _a_
. _b_ is a store, and
_b_ has a syntactic control dependency on _a_
* Pipeline Dependencies
[start=12]
. _b_ is a
load, and there exists some store _m_ between
_a_ and _b_ in program order such that
_m_ has an address or data dependency on _a_,
and _b_ returns a value written by _m_
. _b_ is a store, and
there exists some instruction _m_ between _a_
and _b_ in program order such that _m_ has an
address dependency on _a_

==== 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_.

[[ax-load]]
===== 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:

. Stores that write that byte and that precede _i_ in the
global memory order
. Stores that write that byte and that precede _i_ in
program order

[[ax-atom]]
===== 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.
[NOTE]
====
The <<ax-atom, Atomicity Axiom>> theoretically supports LR/SC pairs of different widths and to
mismatched addresses, 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.
====

[[ax-prog]]
===== Progress Axiom

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

[[csr-granularity]]
=== CSR Dependency Tracking Granularity

.Granularities at which syntactic dependencies are tracked through CSRs
[%autowdith,float="center",align="center",cols="<,<,<",options="header",]
|===
|Name |Portions Tracked as Independent Units |Aliases
|_fflags_ |Bits 4, 3, 2, 1, 0 |_fcsr_
|_frm_ |entire CSR |_fcsr_
|_fcsr_ |Bits 7-5, 4, 3, 2, 1, 0 |_fflags_, _frm_
|===

Note: read-only CSRs are not listed, as they do not participate in the
definition of syntactic dependencies.

[[source-dest-regs]]
=== 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
<<mem-dependencies>>.

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

.RV32I Base Integer Instruction Set
[%autowidth,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
||Source Registers |Destination  Registers|Accumulating CSRs|

|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 † | _rs1_  ^A^ | _rd_ ||

|LH † | _rs1_  ^A^ | _rd_ ||

|LW † | _rs1_  ^A^ | _rd_ ||

|LBU † | _rs1_  ^A^ | _rd_ ||

|LHU † | _rs1_  ^A^ | _rd_ ||

|SB |_rs1_  ^A^, _rs2_ ^D^ | ||

|SH |_rs1_  ^A^, _rs2_ ^D^ | ||

|SW |_rs1_  ^A^, _rs2_ ^D^ | ||

|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_, _rs2_ |_rd_ ||

|SUB |_rs1_, _rs2_ |_rd_ ||

|SLL |_rs1_, _rs2_ |_rd_ ||

|SLT |_rs1_, _rs2_ |_rd_ ||

|SLTU |_rs1_, _rs2_ |_rd_ ||

|XOR |_rs1_, _rs2_ |_rd_ ||

|SRL |_rs1_, _rs2_ |_rd_ ||

|SRA |_rs1_, _rs2_ |_rd_ ||

|OR |_rs1_, _rs2_ |_rd_ ||

|AND |_rs1_, _rs2_ |_rd_ ||

|FENCE | | ||

|FENCE.I | | ||

|ECALL | | ||

|EBREAK | | ||

|CSRRW‡ |_rs1_, _csr_^*^ | _rd_, _csr_ | |^*^unless _rd_=`x0`

|CSRRS‡ |_rs1_, _csr_ |_rd_ ^*^, _csr_ | |^*^unless _rs1_=`x0`

|CSRRC‡ |_rs1_, _csr_  |_rd_ ^*^, _csr_ | |^*^unless _rs1_=`x0`

5+| ‡ carries a dependency from _rs1_ to _csr_ and from _csr_ to _rd_

|CSRRWI ‡ |_csr_ ^*^ |_rd_, _csr_  | |^*^unless _rd_=_x0_

|CSRRSI ‡ |_csr_ |_rd_, _csr_^*^  | |^*^unless uimm[4:0]=0

|CSRRCI ‡ |_csr_ |_rd_, _csr_^*^  | |^*^unless uimm[4:0]=0

5+| ‡ carries a dependency from _csr_ to _rd_
|===

.RV64I Base Integer Instruction Set
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
| |Source Registers |Destination Registers |Accumulating CSRs| 

|_LWU_ † |_rs1_  ^A^ |_rd_ | |

|_LD_ † |_rs1_  ^A^ |_rd_ | |

|SD |_rs1_  ^A^, _rs2_ ^D^ | | |

|SLLI | _rs1_ | _rd_ | |

|SRLI | _rs1_ | _rd_ | |

|SRAI | _rs1_ | _rd_ | |

|ADDIW | _rs1_ | _rd_ | |

|SLLIW | _rs1_ | _rd_ | |

|SRLIW | _rs1_ | _rd_ | |

|SRAIW | _rs1_ | _rd_ | |

|ADDW | _rs1_, _rs2_ |_rd_ ||

|SUBW | _rs1_, _rs2_ |_rd_ ||

|SLLW | _rs1_, _rs2_ |_rd_ ||

|SRLW | _rs1_, _rs2_ |_rd_ ||

|SRAW | _rs1_, _rs2_ |_rd_ ||
|===

.RV32M Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
| |Source Registers |Destination Registers |Accumulating CSRs|

|MUL | _rs1_, _rs2_ |_rd_ ||

|MULH | _rs1_, _rs2_ |_rd_ ||

|MULHSU |_rs1_, _rs2_ |_rd_ ||

|MULHU |_rs1_, _rs2_ |_rd_ ||

|DIV |_rs1_, _rs2_ |_rd_ ||

|DIVU |_rs1_, _rs2_ |_rd_ ||

|REM |_rs1_, _rs2_ |_rd_ ||

|REMU |_rs1_, _rs2_ |_rd_ ||
|===

.RV64M Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
||Source Registers |Destination Registers |Accumulating CSRs|

|MULW |_rs1_, _rs2_ |_rd_ ||

|DIVW |_rs1_, _rs2_ |_rd_ ||

|DIVUW |_rs1_, _rs2_ |_rd_ ||

|REMW |_rs1_, _rs2_ |_rd_ ||

|REMUW |_rs1_, _rs2_ |_rd_ ||
|===

.RV32A Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
||Source Registers |Destination Registers |Accumulating CSRs|

|LR.W† | _rs1_  ^A^ | _rd_ | |

|SC.W† | _rs1_  ^A^, _rs2_ ^D^ | _rd_ ^*^ | | ^*^ if successful

|AMOSWAP.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOADD.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOXOR.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOAND.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOOR.W† |_rs1_ ^A^, _rs2_^D^ |_rd_ | |

|AMOMIN.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOMAX.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOMINU.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|AMOMAXU.W† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ | |

|===

.RV64A Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===

| |Source Registers |Destination Registers |Accumulating CSRs|

|LR.D† |_rs1_  ^A^ |_rd_ | |

|SC.D† |_rs1_ ^A^, _rs2_ ^D^ |_rd_ ^*^ | |^*^if successful

|AMOSWAP.D† |_rs1_  ^A^, _rs2_ ^D^ |_rd_ | |

|AMOADD.D† |_rs1_  ^A^, _rs2_ ^D^ |_rd_ | |

|AMOXOR.D† |_rs1_  ^A^, _rs2_ ^D^ |_rd_ | |

|AMOAND.D† |_rs1_  ^A^, _rs2_^D^ |_rd_ | |

|AMOOR.D† |_rs1_ ^A^, _rs2_^D^ |_rd_ | |

|AMOMIN.D† |_rs1_ ^A^, _rs2_^D^ |_rd_ | |

|AMOMAX.D† |_rs1_ ^A^, _rs2_^D^ |_rd_ | |

|AMOMINU.D† |_rs1_ ^A^, _rs2_^D^ |_rd_ | |

|AMOMAXU.D† |_rs1_ ^A^, _rs2_^D^ |_rd_ | |

|===

.RV32F Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===

| |Source Registers |Destination Registers |Accumulating CSRs |


|FLW† |_rs1_ ^A^ |_rd_ | |

|FSW |_rs1_ ^A^, _rs2_^D^ | | |

|FMADD.S |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FMSUB.S |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FNMSUB.S |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FNMADD.S |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FADD.S |_rs1_, _rs2_, frm^*^ |_rd_ |NV, OF, NX |^*^if rm=111

|FSUB.S |_rs1_, _rs2_, frm^*^ |_rd_ |NV, OF, NX |^*^if rm=111

|FMUL.S |_rs1_, _rs2_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FDIV.S |_rs1_, _rs2_, frm^*^ |_rd_ |NV, DZ, OF, UF, NX |^*^if rm=111

|FSQRT.S |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FSGNJ.S |_rs1_, _rs2_ |_rd_ | |

|FSGNJN.S |_rs1_, _rs2_ |_rd_ | |

|FSGNJX.S |_rs1_, _rs2_ |_rd_ | |

|FMIN.S |_rs1_, _rs2_ |_rd_ |NV |

|FMAX.S |_rs1_, _rs2_ |_rd_ |NV |

|FCVT.W.S |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FCVT.WU.S |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FMV.X.W |_rs1_ |_rd_ | |

|FEQ.S |_rs1_, _rs2_ |_rd_ |NV |

|FLT.S |_rs1_, _rs2_ |_rd_ |NV |

|FLE.S |_rs1_, _rs2_ |_rd_ |NV |

|FCLASS.S |_rs1_ |_rd_ | |

|FCVT.S.W |_rs1_, frm^*^ |_rd_ |NX |^*^if rm=111

|FCVT.S.WU |_rs1_, frm^*^ |_rd_ |NX |^*^if rm=111

|FMV.W.X |_rs1_ |_rd_ | |

|===

.RV64F Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===
| |Source Registers |Destination Registers |Accumulating CSRs|

|FCVT.L.S |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FCVT.LU.S |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FCVT.S.L |_rs1_, frm^*^ |_rd_ |NX |^*^if rm=111

|FCVT.S.LU |_rs1_, frm^*^ |_rd_ |NX |^*^if rm=111

|===

.RV32D Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===

| |Source Registers|Destination Registers |Accumulating CSRs |


|FLD† |_rs1_ ^A^ |_rd_ | |

|FSD |_rs1_ ^A^, _rs2_^D^ | | |

|FMADD.D |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FMSUB.D |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FNMSUB.D |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FNMADD.D |_rs1_, _rs2_, _rs3_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FADD.D |_rs1_, _rs2_, frm^*^ |_rd_ |NV, OF, NX |^*^if rm=111

|FSUB.D |_rs1_, _rs2_, frm^*^ |_rd_ |NV, OF, NX |^*^if rm=111

|FMUL.D |_rs1_, _rs2_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FDIV.D |_rs1_, _rs2_, frm^*^ |_rd_ |NV, DZ, OF, UF, NX |^*^if rm=111

|FSQRT.D |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FSGNJ.D |_rs1_, _rs2_ |_rd_ | |

|FSGNJN.D |_rs1_, _rs2_ |_rd_ | |

|FSGNJX.D |_rs1_, _rs2_ |_rd_ | |

|FMIN.D |_rs1_, _rs2_ |_rd_ |NV |

|FMAX.D |_rs1_, _rs2_ |_rd_ |NV |

|FCVT.S.D |_rs1_, frm^*^ |_rd_ |NV, OF, UF, NX |^*^if rm=111

|FCVT.D.S |_rs1_ |_rd_ |NV |

|FEQ.D |_rs1_, _rs2_ |_rd_ |NV |

|FLT.D |_rs1_, _rs2_ |_rd_ |NV |

|FLE.D |_rs1_, _rs2_ |_rd_ |NV |

|FCLASS.D |_rs1_ |_rd_ | |

|FCVT.W.D |_rs1_,^*^ |_rd_ |NV, NX |^*^if rm=111

|FCVT.WU.D |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FCVT.D.W |_rs1_ |_rd_ | |

|FCVT.D.WU |_rs1_ |_rd_ | |

|===

.RV64D Standard Extension
[%autowidth.stretch,float="center",align="center",cols="<,<,<,<,<",options="header"]
|===

| |Source Registers |Destination Registers |Accumulating CSRs |

|FCVT.L.D |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FCVT.LU.D |_rs1_, frm^*^ |_rd_ |NV, NX |^*^if rm=111

|FMV.X.D |_rs1_ |_rd_ | |

|FCVT.D.L |_rs1_, frm^*^ |_rd_ |NX |^*^if rm=111

|FCVT.D.LU |_rs1_, frm^*^ |_rd_ |NX |^*^if rm=111

|FMV.D.X |_rs1_ |_rd_ | |

|===