From 91832daa19463bd8831bb59284f54700463aca26 Mon Sep 17 00:00:00 2001 From: Brendan Sweeney Date: Sun, 17 Nov 2024 02:43:44 -0600 Subject: [PATCH] Updates in response to ARC feedback. --- chapter2.adoc | 175 ++++++++------------------------------------------ 1 file changed, 28 insertions(+), 147 deletions(-) diff --git a/chapter2.adoc b/chapter2.adoc index ee8156f..3e34b3c 100644 --- a/chapter2.adoc +++ b/chapter2.adoc @@ -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:: ==== @@ -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] @@ -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] ==== @@ -61,60 +64,7 @@ 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. -- <<< @@ -122,7 +72,7 @@ mapping clause assembly = LOADAQ(aq, rl, rs1, size, rd) === 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:: ==== @@ -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:: @@ -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] @@ -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