From 64e0d7a2c87913f7a0a841ebec480628bd4d996e Mon Sep 17 00:00:00 2001 From: Patrick O'Neill Date: Mon, 26 Jun 2023 14:52:38 -0700 Subject: [PATCH] Ztso psABI atomics specification --- riscv-atomic.adoc | 95 ++++++++++++++++++++++++++++++++++++++++------- riscv-elf.adoc | 4 +- 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/riscv-atomic.adoc b/riscv-atomic.adoc index f80a7a36..b8aa220c 100644 --- a/riscv-atomic.adoc +++ b/riscv-atomic.adoc @@ -6,10 +6,10 @@ endif::[] == RISC-V atomics mappings -This specifies mappings of C and C\++ atomic operations to RISC-V +This specifies mappings of C and {Cpp} atomic operations to RISC-V machine instructions. Other languages, for example Java, provide similar facilities that should be implemented in a consistent manner, usually -by applying the mapping for the corresponding C++ primitive. +by applying the mapping for the corresponding {Cpp} primitive. NOTE: Because different programming languages may be used within the same process, these mappings must be compatible across programming languages. For @@ -19,12 +19,12 @@ C. NOTE: Though many mappings are possible, not all of them will interoperate correctly. In particular, many mapping combinations will not -correctly enforce ordering  between a C++ `memory_order_seq_cst` +correctly enforce ordering  between a {Cpp} `memory_order_seq_cst` store and a subsequent `memory_order_seq_cst` load. NOTE: These mappings are very similar to those that originally appeared in the appendix of the RISC-V "unprivileged" architecture specification as -"Mappings from C/C++ primitives to RISC-V Primitives", which we will +"Mappings from C/{Cpp} primitives to RISC-V Primitives", which we will refer to by their 2019 historical label of "Table A.6". That mapping may be used, _except_ that `atomic_store(memory_order_seq_cst)` must have an an extra trailing fence for compatibility with the "Hypothetical mappings ..." @@ -55,10 +55,10 @@ section deals with other read-modify-write operations that require the `lr` and `sc` instructions. [[tab:c11mappings]] -.Mappings from C/C++ primitives to RISC-V primitives +.Mappings from C/{Cpp} primitives to RISC-V primitives [cols="<22,<18,<4",options="header",] |=== -|C/C++ Construct |RVWMO Mapping |Notes +|C/{Cpp} Construct |RVWMO Mapping |Notes |Non-atomic load |`l{b\|h\|w\|d}` | @@ -97,7 +97,7 @@ the `lr` and `sc` instructions. [cols="<20,<20,<4",options="header",] |=== -|C/C++ Construct |RVWMO AMO Mapping |Notes +|C/{Cpp} Construct |RVWMO AMO Mapping |Notes |`atomic_(memory_order_relaxed)` |`amo.{w\|d}` |4 @@ -113,7 +113,7 @@ the `lr` and `sc` instructions. [cols="<16,<24,<4",options="header",] |=== -|C/C++ Construct |RVWMO LR/SC Mapping |Notes +|C/{Cpp} Construct |RVWMO LR/SC Mapping |Notes |`atomic_(memory_order_relaxed)` |`loop:lr.{w\|d}; ; sc.{w\|d}; bnez loop` |4 @@ -136,7 +136,7 @@ the `lr` and `sc` instructions. === Meaning of notes in table 1) Depends on a load instruction with an RCsc aquire annotation, -or a store instruction with an RCsc release annotation. These are curently +or a store instruction with an RCsc release annotation. These are currently under discussion, but the specification has not yet been approved. 2) An RCpc load or store would also suffice, if it were to be introduced @@ -148,11 +148,80 @@ mappings with code generated by a compiler using those older mappings. 4) Currently only directly possible for 32- and 64-bit operands. -=== Other conventions +== Ztso atomics mappings -It is expected that the RVWMO AMO Mappings will be used for atomic read-modify-write -operations that are directly supported by corresponding AMO instructions, -and that LR/SC mappings will be used for the remainder, currently +This specifies additional mappings of C and {Cpp} atomic operations to RISC-V +machine instructions. + +For each construct, we provide a mapping that assumes only the A and Ztso +extension. + +All mappings interoperate correctly with the RVWMO mappings, and with the +original "Table A.6" mappings. + +We present the mappings as a table in 3 sections, as above. + +[[tab:c11mappingsztso]] +.Mappings with Ztso extension from C/{Cpp} primitives to RISC-V primitives +[cols="<22,<18,<4",options="header",] +|=== +|C/{Cpp} Construct |Ztso Mapping |Notes + +|`atomic_load(memory_order_acquire)` |`l{b\|h\|w\|d}` | 5 + +|`atomic_load(memory_order_seq_cst)` |`fence rw,rw; l{b\|h\|w\|d}` | 5 + +|`atomic_store(memory_order_release)` |`s{b\|h\|w\|d}` | 5 + +|`atomic_store(memory_order_seq_cst)` |`s{b\|h\|w\|d}; fence rw, rw` | 5 + +|`atomic_thread_fence(memory_order_acquire)` |`nop` | 5 + +|`atomic_thread_fence(memory_order_release)` |`nop` | 5 + +|`atomic_thread_fence(memory_order_acq_rel)` |`nop` | 5 +|=== + +[cols="<20,<20,<4",options="header",] +|=== +|C/{Cpp} Construct |Ztso AMO Mapping |Notes + +|`atomic_(memory_order_acquire)` |`amo.{w\|d}` |4, 5 + +|`atomic_(memory_order_release)` |`amo.{w\|d}` |4, 5 + +|`atomic_(memory_order_acq_rel)` |`amo.{w\|d}` |4, 5 + +|`atomic_(memory_order_seq_cst)` |`amo.{w\|d}` |4, 5 + +|=== + +[cols="<16,<24,<4",options="header",] +|=== +|C/{Cpp} Construct |Ztso LR/SC Mapping |Notes + +|`atomic_(memory_order_acquire)` +|`loop:lr.{w\|d}; ; sc.{w\|d}; bnez loop` |4, 5 + +|`atomic_(memory_order_release)` +|`loop:lr.{w\|d}; ; sc.{w\|d}; bnez loop` |4, 5 + +|`atomic_(memory_order_acq_rel)` +|`loop:lr.{w\|d}; ; sc.{w\|d}; bnez loop` |4, 5 + +|=== + +=== Meaning of notes in table + +4) Currently only directly possible for 32- and 64-bit operands. + +5) Requires the Ztso extension. + +== Other conventions + +It is expected that the RVWMO and Ztso AMO Mappings will be used for atomic +read-modify-write operations that are directly supported by corresponding AMO +instructions, and that LR/SC mappings will be used for the remainder, currently including compare-exchange operations. Compare-exchange LR/SC sequences on the containing 32-bit word should be used for shorter operands. Thus, a `fetch_add` operation on a 16-bit quantity would use a 32-bit LR/SC sequence. diff --git a/riscv-elf.adoc b/riscv-elf.adoc index 9e341acb..0839c108 100644 --- a/riscv-elf.adoc +++ b/riscv-elf.adoc @@ -266,8 +266,8 @@ raise an error. RVE::: Linker should report errors if object files of different value for RVE field. - TSO::: Linker should report errors if object files of different value - for TSO field. + TSO::: Input files can have different values for the TSO field; the linker + should set this field if any of the input objects have the TSO field set. NOTE: The static linker may ignore the compatibility checks if all fields in the `e_flags` are zero and all sections in the input file are non-executable