diff options
author | Andrew Waterman <andrew@sifive.com> | 2021-10-10 18:07:18 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2021-10-10 20:06:47 -0700 |
commit | 3866430076e92ff0107b2819c39a0b6d8d1162b4 (patch) | |
tree | f8981a900f522103d5b641ea32d5bb5f81638ef4 /src/rv32.adoc | |
parent | 5921e762efd81682f720130a0d72ce8a1a0da16e (diff) | |
download | riscv-isa-manual-3866430076e92ff0107b2819c39a0b6d8d1162b4.zip riscv-isa-manual-3866430076e92ff0107b2819c39a0b6d8d1162b4.tar.gz riscv-isa-manual-3866430076e92ff0107b2819c39a0b6d8d1162b4.tar.bz2 |
Improvements to Intro and RV32I chapters
Just so I don't lose track of it, here are the issues I noticed that
I _didn't_ attempt to address:
Sec. 1.5.1:
- References to the instruction-length encoding figure show up in the text as "[instlengthcode]" instead of "Figure 1.whatever". I guess the reason is that the figure isn't captioned?
- Likewise references to "Chapter [extensions]"
Sec. 1.6:
- "Characteristics of traps" table caption is being rendered incorrectly; it's showing up in garbled form in the main text.
Sec. 2.1:
- Figure 1 is low quality (looks like a screenshot from TeX spec) and needs to be redone.
Sec. 2.9:
- The HINT table was pretty messed up; I tried to fix it, but you should carefully review it.
Sec. 6.2.1:
- Encodings for SRAI and SRAIW are incorrect. Their imm[11:6] field should be 010000, not 100000.
Chapter 16:
- Looks like the C extension chapter needs a lot of work. I don't think it makes sense for me to review it yet.
Diffstat (limited to 'src/rv32.adoc')
-rw-r--r-- | src/rv32.adoc | 147 |
1 files changed, 69 insertions, 78 deletions
diff --git a/src/rv32.adoc b/src/rv32.adoc index ca83464..858230b 100644 --- a/src/rv32.adoc +++ b/src/rv32.adoc @@ -36,13 +36,13 @@ Most of the commentary for RV32I also applies to the RV64I base. === Programmers’ Model for Base Integer ISA <<img-gprs>> 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 +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_ +There is one additional unprivileged register: the program counter `pc` holds the address of the current instruction. [[img-gprs]] @@ -51,17 +51,17 @@ image::base-unpriv-reg-state.png[base,180,1000,align="center"] 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, the standard -software calling convention uses register _x1_ to hold the return -address for a call, with register _x5_ available as an alternate link -register. The standard calling convention uses register _x2_ as the +`x` register to be used for these purposes. However, the standard +software calling convention uses register `x1` to hold the return +address for a call, with register `x5` available as an alternate link +register. The standard calling convention uses register `x2` as the stack pointer. Hardware might choose to accelerate function calls and returns that use -_x1_ or _x5_. See the descriptions of the JAL and JALR instructions. +`x1` or `x5`. See the descriptions of the JAL and JALR instructions. The optional compressed 16-bit instruction format is designed around the -assumption that _x1_ is the return address register and _ x2_ is the +assumption that `x1` is the return address register and `x2` is the stack pointer. Software using other conventions will operate correctly but may have greater code size. @@ -137,7 +137,7 @@ include::images/wavedrom/instruction_formats.adoc[] .RISC-V base instruction formats image::image_placeholder.png[] -Each immediate subfield in <<base_instr>> above 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. +Each immediate subfield in <<base_instr>> above 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. [NOTE] ==== @@ -145,7 +145,7 @@ 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. cite:[spur-jsscc1989]). +RISC-IV aka. SPUR cite:[spur-jsscc1989]). In practice, most immediates are either small or require all XLEN bits. We chose an asymmetric immediate split (12 bits in regular instructions @@ -182,7 +182,7 @@ formats and with each other. <<immtypes>> 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. +instruction bit (inst[_y_]) produces each bit of the immediate value. include::images/wavedrom/immediate.adoc[] [[immtypes]] @@ -192,7 +192,7 @@ image::image_placeholder.png[] [NOTE] ==== Sign-extension is one of the most critical operations on immediates -(particularly for XLEN latexmath:[$>$]32), and in RISC-V the sign bit for +(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. @@ -226,11 +226,11 @@ on integer arithmetic operations in the base instruction set, as many overflow checks can be cheaply implemented using 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_. +`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 the common case +`addi t0, t1, +imm; blt t0, t1, overflow`. This covers the common case of addition with an immediate operand. For general signed addition, three additional instructions after the @@ -296,7 +296,7 @@ LUI (load upper immediate) is used to build 32-bit constants and uses the U-type format. LUI places the 32-bit U-immediate value into the destination register _rd_, filling in the lowest 12 bits with zeros. -AUIPC (add upper immediate to _pc_) is used to build _pc_-relative +AUIPC (add upper immediate to `pc`) is used to build _pc_-relative addresses and uses the U-type format. AUIPC forms a 32-bit offset from the U-immediate, filling in the lowest 12 bits with zeros, adds this offset to the address of the AUIPC instruction, then places the result @@ -304,7 +304,7 @@ in register _rd_. [NOTE] ==== -The assembly syntax for _lui_ and _auipc_ does not represent the lower +The assembly syntax for `lui` and `auipc` does not represent the lower 12 bits of the U-immediate, which are always zero. The AUIPC instruction supports two-instruction sequences to access @@ -337,8 +337,7 @@ 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 -latexmath:[$\mbox{\em rs1} < \mbox{\em - rs2}$], 0 otherwise. Note, SLTU _rd_, _x0_, _rs2_ sets _rd_ to 1 if +_rs1_ < _rs2_, 0 otherwise. Note, 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. @@ -355,7 +354,7 @@ include::images/wavedrom/nop.adoc[] image::image_placeholder.png[] The NOP instruction does not change any architecturally visible state, -except for advancing the _pc_ and incrementing any applicable +except for advancing the `pc` and incrementing any applicable performance counters. NOP is encoded as ADDI _x0, x0, 0_. [NOTE] @@ -396,40 +395,40 @@ The jump and link (JAL) instruction uses the J-type format, where the J-immediate encodes a signed offset in multiples of 2 bytes. The offset is sign-extended and added to the address of the jump instruction to form the jump target address. Jumps can therefore target a -latexmath:[$\pm$] 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 +±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. [NOTE] ==== 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 register _x5_ was chosen as the +the regular return address register. The register `x5` 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. ==== Plain unconditional jumps (assembler pseudoinstruction J) are encoded as -a JAL with _rd_=_x0_. +a JAL with _rd_=`x0`. include::images/wavedrom/ct-unconditional.adoc[] [[ct-unconditional]] -.Plain unconditional jumps +.The unconditional-jump instruction, JAL image::image_placeholder.png[] 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 +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. include::images/wavedrom/ct-unconditional-2.adoc[] [[ct-unconditional-2]] -.Indirect unconditional jump +.The indirect unconditional-jump instruction, JALR image::image_placeholder.png[] [NOTE] @@ -439,7 +438,7 @@ help support position-independent code. The JALR instruction was defined to enable a two-instruction sequence to jump anywhere in a 32-bit absolute address range. A LUI instruction can first load _rs1_ with the upper 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 +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 @@ -455,7 +454,7 @@ 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_latexmath:[$=$]_x0_, JALR can be used to +When used with a base _rs1_=`x0`, JALR can be used to implement a single instruction subroutine call to the lowest or highest address region from anywhere in the address space, which could be used to implement fast calls to a small runtime library. Alternatively, an @@ -479,14 +478,14 @@ 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_ is _x1_ or -_x5_. JALR instructions should push/pop a RAS as shown in <<rashints>>. +address onto a return-address stack (RAS) only when _rd_ is `x1` or +`x5`. JALR instructions should push/pop a RAS as shown in <<rashints>>. [[rashints]] .Return-address stack prediction hints encoded in the register operands of a JALR instruction. [cols="^,^,^,<",options="header"] |=== -|_rd_ is _x1/x5_ |_rs1_ is _x1/x5_ |__rd__latexmath:[$=$]_rs1_ |RAS action +|_rd_ is _x1/x5_ |_rs1_ is _x1/x5_ |_rd_=_rs1_ |RAS action |No |No |-- |None @@ -507,9 +506,9 @@ instructions to guide return-address stack manipulation. We use implicit hinting tied to register numbers and the calling convention to reduce the encoding space used for these hints. -When two different link registers (_x1_ and _x5_) are given as _rs1_ and +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 +_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)_ @@ -521,7 +520,7 @@ 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 -latexmath:[$\pm$]4KiB. +±4 KiB. include::images/wavedrom/ct-conditional.adoc[] [[ct-conditional]] @@ -549,7 +548,7 @@ predicted taken and forward branches as not taken, at least the first time they are encountered. Dynamic predictors should quickly learn any predictable branch behavior. -Unlike some other architectures, the RISC-V jump (JAL with _rd_=_x0_) +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 always-true condition. RISC-V jumps are also PC-relative and support a much wider offset range than @@ -632,7 +631,7 @@ CPU registers. RV32I provides a 32-bit address space that is byte-addressed. The EEI will define what portions of the address space are legal to access with which 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 +`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 @@ -888,7 +887,7 @@ execution to stop and fall back 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 +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 around the EBREAK instruction. Because the RISC-V base ISAs do not provide more than one EBREAK @@ -924,7 +923,7 @@ for semihosting calls in newer designs. RV32I reserves a large encoding space for HINT instructions, which are usually used to communicate performance hints to the microarchitecture. Like the NOP instruction, HINTs do not change any architecturally -visible state, except for advancing the _pc_ and any applicable +visible state, except for advancing the `pc` and any applicable performance counters. Implementations are always allowed to ignore the encoded hints. @@ -937,10 +936,10 @@ a null predecessor or successor set and with _fm_=0. These HINT encodings have been chosen so that simple implementations can ignore HINTs altogether, and instead execute a HINT as a regular instruction that happens not to mutate the architectural state. For -example, ADD is a HINT if the destination register is _x0_; the five-bit +example, ADD is a HINT if the destination register is `x0`; the five-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. +that writes `x0`, which has no architecturally visible effect. As another example, a FENCE instruction with a zero _pred_ field and a zero _fm_ field is a HINT; the _succ_, _rs1_, and _rd_ fields encode the @@ -973,64 +972,56 @@ simulation/emulation. |=== |Instruction |Constraints |Code Points |Purpose -|LUI |_rd_=_x0_ |latexmath:[$2^{20}$] .22+<.>m|_Reserved for future standard use_ +|LUI |_rd_=`x0` |latexmath:[$2^{20}$] .18+<.>m|_Reserved for future standard use_ -|AUIPC |_rd_=_x0_ |latexmath:[$2^{20}$] +|AUIPC |_rd_=`x0` |latexmath:[$2^{20}$] -|ADDI |_rd_=_x0_, and either latexmath:[$2^{17}-1$] _rs1_ latexmath:[$\neq$]_x0_ or _imm_latexmath:[$\neq$]0 | +|ADDI |_rd_=`x0`, and either _rs1_ ≠ `x0` or _imm_≠0 |latexmath:[$2^{17}-1$] -|ANDI |_rd_=_x0_ |latexmath:[$2^{17}$] +|ANDI |_rd_=`x0` |latexmath:[$2^{17}$] -|ORI |_rd_=_x0_ |latexmath:[$2^{17}$] +|ORI |_rd_=`x0` |latexmath:[$2^{17}$] -|XORI |_rd_=_x0_ |latexmath:[$2^{17}$] +|XORI |_rd_=`x0` |latexmath:[$2^{17}$] -|ADD |_rd_=_x0_ |latexmath:[$2^{10}$] +|ADD |_rd_=`x0` |latexmath:[$2^{10}$] -|SUB |_rd_=_x0_ |latexmath:[$2^{10}$] +|SUB |_rd_=`x0` |latexmath:[$2^{10}$] -|AND |_rd_=_x0_ |latexmath:[$2^{10}$] +|AND |_rd_=`x0` |latexmath:[$2^{10}$] -|OR |_rd_=_x0_ |latexmath:[$2^{10}$] +|OR |_rd_=`x0` |latexmath:[$2^{10}$] -|XOR |_rd_=_x0_ |latexmath:[$2^{10}$] +|XOR |_rd_=`x0` |latexmath:[$2^{10}$] -|SLL |_rd_=_x0_ |latexmath:[$2^{10}$] +|SLL |_rd_=`x0` |latexmath:[$2^{10}$] -|SRL |_rd_=_x0_ |latexmath:[$2^{10}$] +|SRL |_rd_=`x0` |latexmath:[$2^{10}$] -|SRA |_rd_=_x0_ |latexmath:[$2^{10}$] +|SRA |_rd_=`x0` |latexmath:[$2^{10}$] -| |_rd_=_x0_| _rs1_latexmath:[$\neq$]_x0_, latexmath:[$2^{10}-63$] +|FENCE|_rd_=`x0`, _rs1_ ≠ `x0`, _fm_=0, and either _pred_=0 or _succ_=0| latexmath:[$2^{10}-63$] -| |_fm_=0, and either _pred_=0 or _succ_=0 |_rd_latexmath:[$\neq$]_x0_ +|FENCE|_rd_ ≠ `x0`, _rs1_=`x0`, _fm_=0, and either _pred_=0 or _succ_=0| latexmath:[$2^{10}-63$] -| | _rs1_=_x0_ |latexmath:[$2^{10}-63$] +|FENCE |_rd_=_rs1_=`x0`, _fm_=0, _pred_=0, _succ_≠0 |15 -| |_fm_=0, and either _pred_=0 or _succ_=0 | +|FENCE |_rd_=_rs1_=`x0`, _fm_=0, _pred_≠W, _succ_≠0 |15 -|FENCE |_rd_=_rs1_=_x0_, _fm_=0 |15 +|FENCE |_rd_=_rs1_=`x0`, _fm_=0, _pred_=W, _succ_=0 |1 |PAUSE -|FENCE |_pred_=0| _succ_latexmath:[$\neq$]0 +|SLTI |_rd_=`x0` |latexmath:[$2^{17}$] .7+<.>m|_Designated for custom use_ -|FENCE |_rd_=_rs1_=_x0_, _fm_=0 |15 +|SLTIU|_rd_=`x0` |latexmath:[$2^{17}$] -|FENCE |_pred_latexmath:[$\neq$]W, _succ_=0 | +|SLLI |_rd_=`x0` |latexmath:[$2^{10}$] -|FENCE |_rd_=_rs1_=_x0_, _fm_=0, _pred_=W, _succ_=0 |1 |PAUSE +|SRLI |_rd_=`x0` |latexmath:[$2^{10}$] -|SLTI |_rd_=_x0_ |latexmath:[$2^{17}$] .7+<.>m|_Designated for custom use_ +|SRAI |_rd_=`x0` |latexmath:[$2^{10}$] -|SLTIU|_rd_=_x0_ |latexmath:[$2^{17}$] +|SLT |_rd_=`x0` |latexmath:[$2^{10}$] -|SLLI |_rd_=_x0_ |latexmath:[$2^{10}$] - -|SRLI |_rd_=_x0_ |latexmath:[$2^{10}$] - -|SRAI |_rd_=_x0_ |latexmath:[$2^{10}$] - -|SLT |_rd_=_x0_ |latexmath:[$2^{10}$] - -|SLTU |_rd_=_x0_ |latexmath:[$2^{10}$] +|SLTU |_rd_=`x0` |latexmath:[$2^{10}$] |=== |