aboutsummaryrefslogtreecommitdiff
path: root/src/m.tex
diff options
context:
space:
mode:
Diffstat (limited to 'src/m.tex')
-rw-r--r--src/m.tex139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/m.tex b/src/m.tex
new file mode 100644
index 0000000..cc289e8
--- /dev/null
+++ b/src/m.tex
@@ -0,0 +1,139 @@
+\chapter{``M'' Standard Extension for Integer Multiplication and
+ Division, Version 2.0}
+
+This chapter describes the standard integer multiplication and
+division instruction extension, which is named ``M'' and contains
+instructions that multiply or divide values held in two integer
+registers.
+
+\begin{commentary}
+We separate integer multiply and divide out from the base to simplify
+low-end implementations, or for applications where integer multiply
+and divide operations are either infrequent or better handled in
+attached accelerators.
+\end{commentary}
+
+\section{Multiplication Operations}
+
+\vspace{-0.2in}
+\begin{center}
+\begin{tabular}{S@{}R@{}R@{}S@{}R@{}O}
+\\
+\instbitrange{31}{25} &
+\instbitrange{24}{20} &
+\instbitrange{19}{15} &
+\instbitrange{14}{12} &
+\instbitrange{11}{7} &
+\instbitrange{6}{0} \\
+\hline
+\multicolumn{1}{|c|}{funct7} &
+\multicolumn{1}{c|}{rs2} &
+\multicolumn{1}{c|}{rs1} &
+\multicolumn{1}{c|}{funct3} &
+\multicolumn{1}{c|}{rd} &
+\multicolumn{1}{c|}{opcode} \\
+\hline
+7 & 5 & 5 & 3 & 5 & 7 \\
+MULDIV & multiplier & multiplicand & MUL/MULH[[S]U] & dest & OP \\
+MULDIV & multiplier & multiplicand & MULW & dest & OP-32 \\
+\end{tabular}
+\end{center}
+
+MUL performs an XLEN-bit$\times$XLEN-bit multiplication and places the
+lower XLEN bits in the destination register. MULH, MULHU, and MULHSU
+perform the same multiplication but return the upper XLEN bits of the
+full 2$\times$XLEN-bit product, for signed$\times$signed,
+unsigned$\times$unsigned, and signed$\times$unsigned multiplication
+respectively. If both the high and low bits of the same product are
+required, then the recommended code sequence is: MULH[[S]U] {\em rdh,
+ rs1, rs2}; MUL {\em rdl, rs1, rs2} (source register specifiers must
+be in same order and {\em rdh} cannot be the same as {\em rs1} or {\em
+ rs2}). Microarchitectures can then fuse these into a single
+multiply operation instead of performing two separate multiplies.
+
+MULW is only valid for RV64, and multiplies the lower
+32 bits of the source registers, placing the sign-extension of the
+lower 32 bits of the result into the destination register. MUL can be
+used to obtain the upper 32 bits of the 64-bit product, but signed
+arguments must be proper 32-bit signed values, whereas unsigned
+arguments must have their upper 32 bits clear.
+
+\section{Division Operations}
+
+\vspace{-0.2in}
+\begin{center}
+\begin{tabular}{S@{}R@{}R@{}O@{}R@{}O}
+\\
+\instbitrange{31}{25} &
+\instbitrange{24}{20} &
+\instbitrange{19}{15} &
+\instbitrange{14}{12} &
+\instbitrange{11}{7} &
+\instbitrange{6}{0} \\
+\hline
+\multicolumn{1}{|c|}{funct7} &
+\multicolumn{1}{c|}{rs2} &
+\multicolumn{1}{c|}{rs1} &
+\multicolumn{1}{c|}{funct3} &
+\multicolumn{1}{c|}{rd} &
+\multicolumn{1}{c|}{opcode} \\
+\hline
+7 & 5 & 5 & 3 & 5 & 7 \\
+MULDIV & divisor & dividend & DIV[U]/REM[U] & dest & OP \\
+MULDIV & divisor & dividend & DIV[U]W/REM[U]W & dest & OP-32 \\
+\end{tabular}
+\end{center}
+
+DIV and DIVU perform signed and unsigned integer division of XLEN
+bits by XLEN bits. REM and REMU provide the remainder of the
+corresponding division operation. If both the quotient and remainder
+are required from the same division, the recommended code sequence is:
+DIV[U] {\em rdq, rs1, rs2}; REM[U] {\em rdr, rs1, rs2} ({\em rdq}
+cannot be the same as {\em rs1} or {\em rs2}). Microarchitectures can
+then fuse these into a single divide operation instead of performing
+two separate divides.
+
+DIVW and DIVUW instructions are only valid for RV64, and divide the
+lower 32 bits of {\em rs1} by the lower 32 bits of {\em rs2}, treating
+them as signed and unsigned integers respectively, placing the 32-bit
+quotient in {\em rd}, sign-extended to 64 bits. REMW and REMUW
+instructions are only valid for RV64, and provide the corresponding
+signed and unsigned remainder operations respectively. Both REMW and
+REMUW sign-extend the 32-bit result to 64 bits.
+
+The semantics for division by zero and division overflow are summarized in
+Table~\ref{tab:divby0}. The quotient of division by zero has all bits set,
+i.e. $2^{XLEN}-1$ for unsigned division or $-1$ for signed division. The
+remainder of division by zero equals the dividend. Signed division overflow
+occurs only when the most-negative integer, $-2^{XLEN-1}$, is divided by $-1$.
+The quotient of signed division overflow is equal to the dividend, and the
+remainder is zero. Unsigned division overflow cannot occur.
+
+\vspace{0.1in}
+\begin{table}[h]
+\center
+\begin{tabular}{|l|c|c||c|c|c|c|}
+\hline
+Condition & Dividend & Divisor & DIVU & REMU & DIV & REM \\ \hline
+Division by zero & $x$ & 0 & $2^{XLEN}-1$ & $x$ & $-1$ & $x$ \\
+Overflow (signed only) & $-2^{XLEN-1}$ & $-1$ & -- & -- & $-2^{XLEN-1}$ & 0 \\
+\hline
+\end{tabular}
+\caption{Semantics for division by zero and division overflow.}
+\label{tab:divby0}
+\end{table}
+
+\begin{commentary}
+We considered raising exceptions on integer divide by zero, with these
+exceptions causing a trap in most execution environments. However,
+this would be the only arithmetic trap in the standard ISA
+(floating-point exceptions set flags and write default values, but do
+not cause traps) and would require language implementors to interact
+with the execution environment's trap handlers for this case.
+Further, where language standards mandate that a divide-by-zero
+exception must cause an immediate control flow change, only a single
+branch instruction needs to be added to each divide operation, and
+this branch instruction can be inserted after the divide and should
+normally be very predictably not taken, adding little runtime
+overhead.
+\end{commentary}