aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2019-05-09 16:37:37 -0700
committerGitHub <noreply@github.com>2019-05-09 16:37:37 -0700
commit0eea1b9d043dfc4e4f573b329b1ed26e0deb7e8f (patch)
treeac954a4d2a1f96361cca106649a9bc2de403f2ac /src
parent169da704eb3eec1c729f98d11532a9b10b7fd158 (diff)
downloadriscv-isa-manual-0eea1b9d043dfc4e4f573b329b1ed26e0deb7e8f.zip
riscv-isa-manual-0eea1b9d043dfc4e4f573b329b1ed26e0deb7e8f.tar.gz
riscv-isa-manual-0eea1b9d043dfc4e4f573b329b1ed26e0deb7e8f.tar.bz2
Clarify reserved/HINT encodings in C chapter text (#382)
This PR essentially copies the information from the encoding table at the end of the chapter into the mainline text. The intent is to remove any doubt about what happens when an instruction's operand constraints are not met.
Diffstat (limited to 'src')
-rw-r--r--src/c.tex75
1 files changed, 54 insertions, 21 deletions
diff --git a/src/c.tex b/src/c.tex
index 912b082..7a2a8fe 100644
--- a/src/c.tex
+++ b/src/c.tex
@@ -32,8 +32,6 @@ on any 16-bit boundary, i.e., IALIGN=16. With the addition of the C
extension, no instructions can raise instruction-address-misaligned
exceptions.
-\pagebreak
-
\begin{commentary}
Removing the 32-bit alignment constraint on the original 32-bit
instructions allows significantly greater code density.
@@ -401,19 +399,23 @@ These instructions use the CI format.
C.LWSP loads a 32-bit value from memory into register {\em rd}. It computes
an effective address by adding the {\em zero}-extended offset, scaled by 4, to
the stack pointer, {\tt x2}. It expands to {\tt lw rd, offset[7:2](x2)}.
-C.LWSP is only valid when $\textit{rd}{\neq}\texttt{x0}$.
+C.LWSP is only valid when $\textit{rd}{\neq}\texttt{x0}$;
+the code points with $\textit{rd}{=}\texttt{x0}$ are reserved.
+
C.LDSP is an RV64C/RV128C-only instruction that loads a 64-bit value from memory into
register {\em rd}. It computes its effective address by adding the
zero-extended offset, scaled by 8, to the stack pointer, {\tt x2}.
It expands to {\tt ld rd, offset[8:3](x2)}.
-C.LDSP is only valid when $\textit{rd}{\neq}\texttt{x0}$.
+C.LDSP is only valid when $\textit{rd}{\neq}\texttt{x0}$;
+the code points with $\textit{rd}{=}\texttt{x0}$ are reserved.
C.LQSP is an RV128C-only instruction that loads a 128-bit value from memory
into register {\em rd}. It computes its effective address by adding the
zero-extended offset, scaled by 16, to the stack pointer, {\tt x2}.
It expands to {\tt lq rd, offset[9:4](x2)}.
-C.LQSP is only valid when $\textit{rd}{\neq}\texttt{x0}$.
+C.LQSP is only valid when $\textit{rd}{\neq}\texttt{x0}$;
+the code points with $\textit{rd}{=}\texttt{x0}$ are reserved.
C.FLWSP is an RV32FC-only instruction that loads a single-precision
floating-point value from memory into floating-point register {\em rd}. It
@@ -686,11 +688,15 @@ These instructions use the CR format.
C.JR (jump register) performs an unconditional control transfer to
the address in register {\em rs1}. C.JR expands to {\tt jalr x0, 0(rs1)}.
+C.JR is only valid when $\textit{rs1}{\neq}\texttt{x0}$; the code point
+with $\textit{rs1}{=}\texttt{x0}$ is reserved.
C.JALR (jump and link register) performs the same operation as C.JR,
but additionally writes the address of the instruction following the
jump ({\tt pc}+2) to the link register, {\tt x1}. C.JALR expands to
{\tt jalr x1, 0(rs1)}.
+C.JALR is only valid when $\textit{rs1}{\neq}\texttt{x0}$; the code point
+with $\textit{rs1}{=}\texttt{x0}$ corresponds to the C.EBREAK instruction.
\begin{commentary}
Strictly speaking, C.JALR does not expand exactly to a base RVI
@@ -761,15 +767,21 @@ C.LUI & nzimm[17] & $\textrm{dest}{\neq}{\left\{0,2\right\}}$ & nzimm[16:12]
\end{tabular}
\end{center}
C.LI loads the sign-extended 6-bit immediate, {\em imm}, into
-register {\em rd}. C.LI is only valid when {\em rd}$\neq${\tt x0}.
+register {\em rd}.
C.LI expands into {\tt addi rd, x0, imm[5:0]}.
+C.LI is only valid when {\em rd}$\neq${\tt x0};
+the code points with {\em rd}={\tt x0} encode HINTs.
C.LUI loads the non-zero 6-bit immediate field into bits 17--12 of the
destination register, clears the bottom 12 bits, and sign-extends bit
-17 into all higher bits of the destination. C.LUI is only valid when
+17 into all higher bits of the destination.
+C.LUI expands into {\tt lui rd, nzimm[17:12]}.
+C.LUI is only valid when
$\textit{rd}{\neq}{\left\{\texttt{x0},\texttt{x2}\right\}}$,
and when the immediate is not equal to zero.
-C.LUI expands into {\tt lui rd, nzimm[17:12]}.
+The code points with {\em nzimm}=0 are reserved; the remaining code points
+with {\em rd}={\tt x0} are HINTs; and the remaining code points with
+{\em rd}={\tt x2} correspond to the C.ADDI16SP instruction.
\subsection*{Integer Register-Immediate Operations}
@@ -804,12 +816,15 @@ C.ADDI adds the non-zero sign-extended 6-bit immediate to the value in
register {\em rd} then writes the result to {\em rd}. C.ADDI expands
into {\tt addi rd, rd, nzimm[5:0]}.
C.ADDI is only valid when {\em rd}$\neq${\tt x0}.
+The code point with both {\em rd}={\tt x0} and {\em nzimm}=0 encodes the C.NOP instruction;
+the remaining code points with either {\em rd}={\tt x0} or {\em nzimm}=0 encode HINTs.
C.ADDIW is an RV64C/RV128C-only instruction that performs the same
computation but produces a 32-bit result, then sign-extends result to
64 bits. C.ADDIW expands into {\tt addiw rd, rd, imm[5:0]}. The
immediate can be zero for C.ADDIW, where this corresponds to {\tt
-sext.w rd}. C.ADDIW is only valid when {\em rd}$\neq${\tt x0}.
+sext.w rd}. C.ADDIW is only valid when {\em rd}$\neq${\tt x0};
+the code points with {\em rd}={\tt x0} are reserved.
C.ADDI16SP shares the opcode with C.LUI, but has a destination field
of {\tt x2}. C.ADDI16SP adds the non-zero sign-extended 6-bit immediate to
@@ -817,6 +832,8 @@ the value in the stack pointer ({\tt sp}={\tt x2}), where the
immediate is scaled to represent multiples of 16 in the range
(-512,496). C.ADDI16SP is used to adjust the stack pointer in procedure
prologues and epilogues. It expands into {\tt addi x2, x2, nzimm[9:4]}.
+C.ADDI16SP is only valid when {\em nzimm}$\neq$0;
+the code point with {\em nzimm}=0 is reserved.
\begin{commentary}
In the standard RISC-V calling convention, the stack pointer {\tt sp}
@@ -846,7 +863,8 @@ non-zero immediate, scaled by 4, to the stack pointer, {\tt x2}, and
writes the result to {\tt \rdprime}. This instruction is used
to generate pointers to stack-allocated variables, and expands to
{\tt addi \rdprime, x2, nzuimm[9:2]}.
-
+C.ADDI4SPN is only valid when {\em nzuimm}$\neq$0;
+the code points with {\em nzuimm}=0 are reserved.
\vspace{-0.4in}
\begin{center}
@@ -871,12 +889,16 @@ C.SLLI & shamt[5] & dest$\neq$0 & shamt[4:0] & C2 \\
C.SLLI is a CI-format instruction that performs a logical left shift
of the value in register {\em rd} then writes the result to {\em rd}.
-The shift amount is encoded in the {\em shamt} field, where {\em
- shamt[5]} must be zero for RV32C. For RV32C and RV64C, the shift
-amount must be non-zero. For RV128C, a shift amount of zero is used
-to encode a shift of 64. C.SLLI expands into {\tt slli rd, rd,
- shamt[5:0]}, except for RV128C with {\tt shamt=0}, which expands to
-{\tt slli rd, rd, 64}.
+The shift amount is encoded in the {\em shamt} field.
+For RV128C, a shift amount of zero is used to encode a shift of 64.
+C.SLLI expands into {\tt slli rd, rd, shamt[5:0]}, except for
+RV128C with {\tt shamt=0}, which expands to {\tt slli rd, rd, 64}.
+
+For RV32C, {\em shamt[5]} must be zero; the code points with {\em shamt[5]}=1
+are reserved for custom extensions. For RV32C and RV64C, the shift
+amount must be non-zero; the code points with {\em shamt}=0 are HINTs. For
+all base ISAs, the code points with {\em rd}={\tt x0} are HINTs, except those
+with {\em shamt[5]}=1 in RV32C.
\vspace{-0.4in}
\begin{center}
@@ -904,15 +926,18 @@ C.SRAI & shamt[5] & C.SRAI & dest & shamt[4:0] & C1 \\
C.SRLI is a CB-format instruction that performs a logical right shift
of the value in register {\em \rdprime} then writes the result to {\em \rdprime}.
-The shift amount is encoded in the {\em shamt} field, where {\em
- shamt[5]} must be zero for RV32C. For RV32C and RV64C, the shift
-amount must be non-zero. For RV128C, a shift amount of zero is used
-to encode a shift of 64. Furthermore, the shift amount is sign-extended
+The shift amount is encoded in the {\em shamt} field.
+For RV128C, a shift amount of zero is used to encode a shift of 64.
+Furthermore, the shift amount is sign-extended
for RV128C, and so the legal shift amounts are 1--31, 64, and 96--127.
C.SRLI expands into {\tt srli \rdprime, \rdprime, shamt[5:0]},
except for RV128C with {\tt shamt=0}, which expands to
{\tt srli \rdprime, \rdprime, 64}.
+For RV32C, {\em shamt[5]} must be zero; the code points with {\em shamt[5]}=1
+are reserved for custom extensions. For RV32C and RV64C, the shift
+amount must be non-zero; the code points with {\em shamt}=0 are HINTs.
+
C.SRAI is defined analogously to C.SRLI, but instead performs an arithmetic
right shift.
C.SRAI expands to {\tt srai \rdprime, \rdprime, shamt[5:0]}.
@@ -982,6 +1007,10 @@ These instructions use the CR format.
C.MV copies the value in register {\em rs2} into register {\em rd}. C.MV
expands into {\tt add rd, x0, rs2}.
+C.MV is only valid when $\textit{rs2}{\neq}\texttt{x0}$; the code points
+with $\textit{rs2}{=}\texttt{x0}$ correspond to the C.JR instruction.
+The code points with $\textit{rs2}{\neq}\texttt{x0}$ and
+$\textit{rd}{=}\texttt{x0}$ are HINTs.
\begin{commentary}
C.MV expands to a different instruction than the canonical MV
@@ -992,6 +1021,10 @@ to expand C.MV to MV instead of ADD, at slight additional hardware cost.
C.ADD adds the values in registers {\em rd} and {\em rs2} and writes the
result to register {\em rd}. C.ADD expands into {\tt add rd, rd, rs2}.
+C.ADD is only valid when $\textit{rs2}{\neq}\texttt{x0}$; the code points
+with $\textit{rs2}{=}\texttt{x0}$ correspond to the C.JALR and C.EBREAK instructions.
+The code points with $\textit{rs2}{\neq}\texttt{x0}$ and
+$\textit{rd}{=}\texttt{x0}$ are HINTs.
\vspace{-0.4in}
\begin{center}
@@ -1222,7 +1255,7 @@ than 16 bits, including those in the base ISAs. Several instructions
are only valid for certain operands; when invalid, they are marked
either {\em RES} to indicate that the opcode is reserved for future
standard extensions; {\em NSE} to indicate that the opcode is reserved
-for non-standard extensions; or {\em HINT} to indicate that the opcode
+for custom extensions; or {\em HINT} to indicate that the opcode
is reserved for microarchitectural hints (see Section~\ref{sec:rvc-hints}).
\input{rvc-opcode-map}