diff options
author | Andrew Waterman <andrew@sifive.com> | 2019-05-09 16:37:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-09 16:37:37 -0700 |
commit | 0eea1b9d043dfc4e4f573b329b1ed26e0deb7e8f (patch) | |
tree | ac954a4d2a1f96361cca106649a9bc2de403f2ac /src | |
parent | 169da704eb3eec1c729f98d11532a9b10b7fd158 (diff) | |
download | riscv-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.tex | 75 |
1 files changed, 54 insertions, 21 deletions
@@ -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} |