Skip to content

Commit

Permalink
Updates in response to ARC feedback.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendan Sweeney committed Nov 17, 2024
1 parent 8128bf2 commit 91832da
Showing 1 changed file with 28 additions and 147 deletions.
175 changes: 28 additions & 147 deletions chapter2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
=== Load Acquire

Synopsis::
The load-acquire instruction, atomically and subject to the ordering annotations specified in the instruction, loads a size-byte value from the address in _rs1_ into the register _rd_.
The load-acquire instruction, atomically and subject to the ordering annotations specified in the instruction, loads a 2^width^-byte value from the address in _rs1_ into the register _rd_.

Mnemonic::
====
Expand All @@ -17,8 +17,6 @@ lh.{aq,aqrl} _rd_, (_rs1_)
lw.{aq,aqrl} _rd_, (_rs1_)
ld.{aq,aqrl} _rd_, (_rs1_)
lq.{aq,aqrl} _rd_, (_rs1_)
====
Encoding::
[wavedrom, ,svg]
Expand All @@ -30,24 +28,29 @@ Encoding::
{bits: 5, name: 'rs1', attr: ['5', 'addr'], type: 4},
{bits: 5, name: 'rs2', attr: ['5', '0'], type: 4},
{bits: 1, name: 'rl', attr: ['1', 'ring'], type: 8},
{bits: 1, name: 'aq', attr: ['1', 'orde'], type: 8},
{bits: 5, name: 'funct5', attr: ['5', 'Load Ordered', '00110'], type: 8},
{bits: 1, name: 'aq', attr: ['1', 'orde', '1'], type: 8},
{bits: 5, name: 'funct5', attr: ['5', 'Load Acquire', '00110'], type: 8},
]}
....

Description::

This instruction loads size bytes of memory from rs1 atomically.
This instruction loads 2^width^ bytes of memory from rs1 atomically.
If the size is less than XLEN, it is sign-extended to fill the destination register.
This load must have the ordering annotation _aq_, and may have ordering annotation _rl_ encoded in the instruction: if the bit _aq_ is set, the instruction has an "acquire-RCsc" annotation, and if the bit _rl_ is set, the instruction has a "release-RCsc" annotation.
The address held in _rs1_ should be naturally aligned to the size of the operand.

The Zalasr extension requires that the address held in _rs1_ be naturally aligned to the size of the operand.
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 be emulated.
The misaligned atomicity granule PMA applies to the instructions in this extension.

The misaligned atomicity granule PMA, defined in Volume II of this manual, optionally relaxes this alignment requirement.
If present, the misaligned atomicity granule PMA specifies the size of a misaligned atomicity granule, a power-of-two number of bytes.
The misaligned atomicity granule PMA applies to instructions in the Zalasr extension in addition to AMOs, loads and stores defined in the base ISAs, and loads and stores of no more than XLEN bits defined in the F, D, and Q extensions.
For an instruction in that set, if all accessed bytes lie within the same misaligned atomicity granule, the instruction will not raise an exception for reasons of address alignment, and the instruction will give rise to only one memory operation for the purposes of RVWMO—i.e., it will execute atomically.

The versions without the _aq_ bit set are RESERVED.
RV32 shall not implement the d and q variants and RV64 shall not implement the q variant.
ld.{aq, aqrl} is RV64-only.

funct5 for this instruction is 00110.

[NOTE]
====
Expand All @@ -61,68 +64,15 @@ Load-release has theoretical applications in seqlocks, but is not supported in l
SAIL code::
[source,sail]
--
union clause ast = LOADAQ : (bool, bool, regidx, size, regidx)

mapping clause encdec = LOADAQ(aq, rl, rs1, size, rd) if haveZalasr()
<-> 0b00110 @ bool_bits(aq) @ bool_bits(rl) @ 0b00000 @ rs1 @ 0b0 @ size_bits(size) @ rd @ 0b0101111 if haveZalasr()

val process_loadaq : forall 'n, 0 < 'n <= xlen_bytes. (regidx, xlenbits, MemoryOpResult(bits(8 * 'n)), bool) -> Retired
function process_loadaq (rd, addr, value, is_unsigned) =
match extend_value(is_unsigned, value) {
MemValue(result) => { X(rd) = result; RETIRE_SUCCESS },
MemException(e) => { handle_mem_exception(addr, e); RETIRE_FAIL }
}

function clause execute(LOADRES(aq, rl, rs1, width, rd)) = {
if haveZalasr() then {
/* Get the address, X(rs1) (no offset).
* Extensions might perform additional checks on address validity.
*/
match ext_data_get_addr(rs1, zeros(), Read(Data), width) {
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
Ext_DataAddr_OK(vaddr) => {
let aligned : bool =
match width {
BYTE => true,
HALF => vaddr[0..0] == 0b0,
WORD => vaddr[1..0] == 0b00,
DOUBLE => vaddr[2..0] == 0b000
};
if not(aligned)
then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }
else match translateAddr(vaddr, Read(Data)) {
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
TR_Address(addr, _) =>
match (width, sizeof(xlen)) {
(BYTE, _) => process_loadaq(rd, vaddr, mem_read(Read(Data), addr, 1, aq, aq & rl, true), false),
(HALF, _) => process_loadaq(rd, vaddr, mem_read(Read(Data), addr, 2, aq, aq & rl, true), false),
(WORD, _) => process_loadaq(rd, vaddr, mem_read(Read(Data), addr, 4, aq, aq & rl, true), false),
(DOUBLE, 64) => process_loadaq(rd, vaddr, mem_read(Read(Data), addr, 8, aq, aq & rl, true), false),
_ => internal_error(__FILE__, __LINE__, "Unexpected Load-acquire width")
}
}
}
}
} else {
handle_illegal();
RETIRE_FAIL
}
}

mapping clause assembly = LOADAQ(aq, rl, rs1, size, rd)
<-> "l" ^ size_mnemonic(size)
^ "." ^ maybe_aq(aq) ^ maybe_rl(rl)
^ spc() ^ reg_(rd)
^ sep() ^ "(" ^ reg_name(rs1) ^ ")"

Not included in this specification.
--

<<<
[#insns-sdatomic,reftext="Store Release"]
=== Store Release

Synopsis::
The store-release instruction, atomically and subject to the ordering annotations specified in the instruction, stores the size-byte value from the register _rs2_ to the address in _rs1_.
The store-release instruction, atomically and subject to the ordering annotations specified in the instruction, stores the 2^width^-byte value from the register _rs2_ to the address in _rs1_.

Mnemonic::
====
Expand All @@ -133,8 +83,6 @@ sh.{rl,aqrl} _rs2_, (_rs1_)
sw.{rl,aqrl} _rs2_, (_rs1_)
sd.{rl,aqrl} _rs2_, (_rs1_)
sq.{rl,aqrl} _rs2_, (_rs1_)
====

Encoding::
Expand All @@ -146,24 +94,28 @@ Encoding::
{bits: 3, name: 'funct3', attr: ['3', 'width'], type: 8},
{bits: 5, name: 'rs1', attr: ['5', 'addr'], type: 4},
{bits: 5, name: 'rs2', attr: ['5', 'src'], type: 4},
{bits: 1, name: 'rl', attr: ['1', 'ring'], type: 8},
{bits: 1, name: 'rl', attr: ['1', 'ring', '1'], type: 8},
{bits: 1, name: 'aq', attr: ['1', 'orde'], type: 8},
{bits: 5, name: 'funct5', attr: ['5', 'Store Ordered', '00111'], type: 8},
{bits: 5, name: 'funct5', attr: ['5', 'Store Release', '00111'], type: 8},
]}
....

Description::

This instruction stores size bytes of memory from rs1 atomically.
This instruction stores 2^width^ bytes of memory from rs1 atomically.
This store must have ordering annotation _rl_, and may have ordering annotation _aq_ encoded in the instruction: if the bit _aq_ is set, the instruction has an "acquire-RCsc" annotation, and if the bit _rl_ is set, the instruction has a "release-RCsc" annotation.
The address held in _rs1_ should be naturally aligned to the size of the operand.

The Zalasr extension requires that the address held in _rs1_ be naturally aligned to the size of the operand.
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 be emulated.
If the Zam standard extension is implemented, the address is not required to be aligned and the weaker atomicity guarantee provided by Zam applies.
The versions without the _rl_ bit set are RESERVED.
RV32 shall not implement the d and q variants and RV64 shall not implement the q variant.

funct5 for this instruction is 00111.
The misaligned atomicity granule PMA, defined in Volume II of this manual, optionally relaxes this alignment requirement.
If present, the misaligned atomicity granule PMA specifies the size of a misaligned atomicity granule, a power-of-two number of bytes.
The misaligned atomicity granule PMA applies to instructions in the Zalasr extension in addition to AMOs, loads and stores defined in the base ISAs, and loads and stores of no more than XLEN bits defined in the F, D, and Q extensions.
For an instruction in that set, if all accessed bytes lie within the same misaligned atomicity granule, the instruction will not raise an exception for reasons of address alignment, and the instruction will give rise to only one memory operation for the purposes of RVWMO—i.e., it will execute atomically.

The versions without the _rl_ bit set are RESERVED.
sd.{rl, aqrl} is RV64-only.


[NOTE]
Expand All @@ -178,76 +130,5 @@ Store-acquire has theoretical applications in seqlocks, but is not supported in
SAIL code::
[source,sail]
--
union clause ast = STORERL : (bool, bool, regidx, regidx, word_width)
mapping clause encdec = STORERL(aq, rl, rs2, rs1, size) if haveZalasr()
<-> 0b00111 @ bool_bits(aq) @ bool_bits(rl) @ rs2 @ rs1 @ 0b0 @ size_bits(size) @ 0b00000 @ 0b0101111 if haveZalasr()

/* NOTE: Currently, we only EA if address translation is successful. This may need revisiting. */
function clause execute (STORERL(aq, rl, rs2, rs1, width)) = {
if havaZalasr() then {
/* Get the address, X(rs1) (no offset).
* Extensions might perform additional checks on address validity.
*/
match ext_data_get_addr(rs1, zeros(), Write(Data), width) {
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
Ext_DataAddr_OK(vaddr) => {
let aligned : bool =
match width {
BYTE => true,
HALF => vaddr[0..0] == 0b0,
WORD => vaddr[1..0] == 0b00,
DOUBLE => vaddr[2..0] == 0b000
};
if not(aligned)
then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }
else {
match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:
* both result in a SAMO exception */
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
TR_Address(addr, _) => {
let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {
(BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),
(HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),
(WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),
(DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),
_ => internal_error(__FILE__, __LINE__, "Unexpected Store-release width")
};
match (eares) {
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
MemValue(_) => {
rs2_val = X(rs2);
let res : MemoryOpResult(bool) = match (width, sizeof(xlen)) {
(BYTE, _) => mem_write_value(addr, 1, rs2_val[7..0], aq & rl, rl, true),
(HALF, _) => mem_write_value(addr, 2, rs2_val[15..0], aq & rl, rl, true),
(WORD, _) => mem_write_value(addr, 4, rs2_val[31..0], aq & rl, rl, true),
(DOUBLE, 64) => mem_write_value(addr, 8, rs2_val, aq & rl, rl, true),
_ => internal_error(__FILE__, __LINE__, "Unexpected Store-release width")
};
match (res) {
MemValue(_) => { RETIRE_SUCCESS },
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }
}
}
}
}
}
}
}
}
} else {
handle_illegal();
RETIRE_FAIL
}
}

mapping clause assembly = STORERL(aq, rl, rs2, rs1, size)
<-> "s" ^ size_mnemonic(size)
^ "." ^ maybe_aq(aq) ^ maybe_rl(rl)
^ spc() ^ reg_name(rs2)
^ sep() ^ "(" ^ reg_name(rs1) ^ ")"


Not included in this specification.
--


// store-ordered funct5 = 00111

0 comments on commit 91832da

Please sign in to comment.