\documentclass[a4paper]{article}

\usepackage{array}
\usepackage{baskervald}
\usepackage[british]{babel}
\usepackage{booktabs}
\usepackage{courierten}
\usepackage{graphicx}
\usepackage[utf8]{inputenc}
\usepackage{multirow}
\usepackage{nameref}
\usepackage{parskip}
\usepackage{sectsty}
\usepackage{tabularx}
\usepackage{helvet}

% Custom title format
\renewcommand{\title}[1]{\def\thetitle{#1}}
\renewcommand{\author}[1]{\def\theauthor{#1}}
\renewcommand{\date}[1]{\def\thedate{#1}}
\newcommand{\version}[1]{\def\theversion{#1}}
\newcommand{\versiondatesep}{\hskip 0.5em \textperiodcentered \hskip 0.5em}
\renewcommand{\maketitle}{
  \null
  \vskip 3em
  \begin{center}
    {\LARGE\sffamily\bfseries \thetitle}
    \par
    {\large \theauthor}
    \par
    \vskip 0.5em
    {\itshape \theversion \versiondatesep \thedate}
  \end{center}
  \par
  \vskip 4em
}

% Make all section headings sans-serif
\allsectionsfont{\sffamily}

% Commands for operations table
\newcommand{\noopcode}{--}
\newcommand{\op}[1]{\texttt{#1}}
\newcommand{\opsep}{\multicolumn{1}{c}{}}
\newcommand{\opfamily}[2]{
  \midrule\multicolumn{1}{c}{\multirow{#1}{*}{\rotatebox{90}{\textbf{#2}}}}}

% Column type for bit-layout figures
\newcolumntype{B}{>{\centering\tiny\bfseries\arraybackslash}X}

\title{ETD32 ISA Specification}
\author{Camden Dixie O'Brien}
\version{Version 0.1.0-draft}
\date{\today}

\begin{document}

\maketitle

The ETD32 ISA is a little-endian, 32-bit RISC architecture, designed
to be simple and relatively easy to implement. It is primarily
intended for educational use, such as teaching processor internals and
design, assembly language programming and compiler development.

\section{Registers}

There are a total of 32 directly addressable registers, which are
uniquely identified by their 5-bit register number.  The Z register
(register number 0) is a special ``black hole'' register: any writes
to this register have no effect and when read it always yields zero.

\begin{table}[h]
  \centering
  \begin{tabular}{lrl}
    \toprule
    \textbf{Name} & \textbf{Number} & \textbf{Purpose} \\
    \midrule
    Z & 0 & ``Black hole'' pseudo-register \\
    R1--R29 & 1--29 & General purpose \\
    SP & 30 & Stack pointer \\
    PC & 31 & Program counter \\
    \bottomrule
  \end{tabular}
  \caption{List of Registers}
\end{table}

In addition to these, there is a flags register which cannot be
addressed directly but affects conditional execution of commands. See
section \ref{sec:conditional-execution} for more details.

\section{Addressing Modes}

\subsection{Register Direct (RD)}

\begin{center}
  \texttt{Op R\textsubscript{dest},R\textsubscript{x},R\textsubscript{y}}
\end{center}

In register direct mode, the operands consist of up to three register
numbers. The first register is a destination; the second and third are
inputs.

\subsection{Register-Immediate (RI)}

\begin{center}
  \texttt{Op R\textsubscript{dest},R\textsubscript{x},\#I\textsubscript{y}}
\end{center}

Register-immediate instructions have a destination register and a
single source register, with the rest of the instruction being a
signed, 12-bit immediate value.

\subsection{Base-Offset (BO)}

\begin{center}
  \texttt{
    Op R\textsubscript{target},[R\textsubscript{base},\#I\textsubscript{offset}]}
\end{center}

Base-offset addressing uses a target register---which may be used as
input or output depending on the operation---a base register and a
12-bit immediate value (the offset). The offset is added to the value
of the base register, and this is used as a memory address.

\subsection{Base-Index (BI)}

\begin{center}
  \texttt{
    Op R\textsubscript{target},[R\textsubscript{base},R\textsubscript{index}]}
\end{center}

Base-index addressing is similar to base-offset addressing, except an
index register is provided instead of an offset immediate. The values
of the base and index registers are added together and used as a
memory address.

\subsection{Immediate (I)}

\begin{center}
  \texttt{Op \#I}
\end{center}

The simplest addressing mode; immediate instructions specify a single,
signed, 22-bit immediate value.

\section{Conditional Execution}
\label{sec:conditional-execution}

Instructions which yield a value (logic and arithmetic or memory load
operations) set the condition flags, which are stored in the flags
register. Any flags that are not set by an operation are implicitly
cleared.

\begin{table}[h]
  \centering
  \begin{tabular}{rl}
    \toprule
    \textbf{Flag} & \textbf{Description} \\
    \midrule
    C & Carry / overflow \\
    N & Less than zero \\
    Z & Equal to zero \\
    P & Greater than zero \\
    \bottomrule
  \end{tabular}
  \caption{Condition flags}
  \label{tab:condition-flags}
\end{table}

All instructions can be conditionally executed depending on any
combination of the four condition flags in the flag register. This is
conventionally denoted by appending the character codes of all flags
that should be depended on to the mnemonic. For example, a suffix of
\texttt{NP} would indicate that the instruction should only be
executed if the \texttt{N} and \texttt{P} flags are both set---that
is, if the previous command yielded a value that was not equal to
zero.

\section{Instruction Set}

There are a total of 18 distinct operations, with 33 opcodes (each
addressing mode variant of a command has its own opcode). They fall
into three categories: \emph{Logic \& Arithmetic}, \emph{Memory}
and \emph{Flow Control}. Refer to table \ref{tab:operations} for an
exhaustive list of these operations and their opcodes.

\begin{table}[p]
  \renewcommand{\arraystretch}{1.2}
  \begin{tabularx}{\textwidth}{cl*{5}{r}X}
    \toprule
    \multicolumn{2}{c}{\multirow{2}{*}{\textbf{Operation}}} &
    \multicolumn{5}{c}{\textbf{Opcode}} &
    \multirow{2}{*}{\textbf{Description}} \\
    \cmidrule(r){3-7}
    &
    & \multicolumn{1}{c}{RD} & \multicolumn{1}{c}{RI}
    & \multicolumn{1}{c}{BO} & \multicolumn{1}{c}{BI}
    & \multicolumn{1}{c}{I} & \\

    \opfamily{13}{Logic \& Arithmetic} &
    \op{LLS} & 0 & 1 & \noopcode & \noopcode & \noopcode &
    Applies a logical left shift to its first input; the second input
    determines the number of places \\

    \opsep &
    \op{LRS} & 2 & 3 & \noopcode & \noopcode & \noopcode &
    Logical right shift; otherwise the same as \texttt{LLS} \\

    \opsep &
    \op{AND} & 4 & 5 & \noopcode & \noopcode & \noopcode &
    Bitwise \texttt{AND}s its inputs \\

    \opsep &
    \op{OR} & 6 & 7 & \noopcode & \noopcode & \noopcode &
    Bitwise \texttt{OR}s its inputs \\

    \opsep &
    \op{XOR} & 8 & 9 & \noopcode & \noopcode & \noopcode &
    Bitwise \texttt{XOR}s its inputs \\

    \opsep &
    \op{NOT} & 10 & \noopcode & \noopcode & \noopcode & \noopcode &
    Bitwise \texttt{NOT}s its first input. The second input is ignored. \\

    \opsep &
    \op{ADD} & 11 & 12 & \noopcode & \noopcode & \noopcode &
    Adds its inputs \\

    \opsep &
    \op{SUB} & 13 & 14 & \noopcode & \noopcode & \noopcode &
    Subtracts its second input from its first (two's complement) \\

    \opsep &
    \op{MUL} & 15 & 16 & \noopcode & \noopcode & \noopcode &
    Multiplies its inputs \\

    \opfamily{9.3}{Memory} &
    \op{LD8} & \noopcode & \noopcode & 17 & 18 & \noopcode &
    Loads a byte from the address in memory and writes it to the
    target register \\

    \opsep & \op{LD16} & \noopcode & \noopcode & 19 & 20 & \noopcode &
    Same as \texttt{LD8}, but a half-word \\

    \opsep & \op{LD32} & \noopcode & \noopcode & 21 & 22 & \noopcode &
    Same as \texttt{LD8}, but a full word \\

    \opsep &
    \op{ST8} & \noopcode & \noopcode & 23 & 24 & \noopcode &
    Writes the least-significant byte of the contents of the target register
    to the memory address \\

    \opsep &
    \op{ST16} & \noopcode & \noopcode & 25 & 26 & \noopcode &
    Same as \texttt{ST8} but a half-word \\

    \opsep &
    \op{ST32} & \noopcode & \noopcode & 27 & 28 & \noopcode &
    Same as \texttt{ST8} but a full word \\

    \opfamily{6.3}{Flow control} &
    \op{B} & \noopcode & \noopcode & \noopcode & \noopcode & 29 &
    Jump to the given offset from the PC; argument must be a multiple of 4 \\

    \opsep &
    \op{JMP} & 30 & \noopcode & \noopcode & \noopcode & 31 &
    Jump to the given address; must be word-aligned. For the \texttt{RD}
    variant, only the first source register is used. \\

    \opsep &
    \op{TI} & \noopcode & \noopcode & \noopcode & \noopcode & 32 &
    Trigger a software interrupt; the argument is ignored \\
    \bottomrule
  \end{tabularx}
  \caption{Operations and their Opcodes}
  \label{tab:operations}
\end{table}

\section{Instruction Encoding}

All instructions are 32-bits wide and have a 4-bit condition code in
the most-significant position, directly followed by a 6-bit
opcode. Each bit in the condition code corresponds to one of the flags
(see figure \ref{fig:instruction-encoding} for the order); the bit
being set indicates that execution of the command should depend on the
corresponding flag being set.

\begin{figure}[h]
  \renewcommand{\arraystretch}{1.2}
  \centering
  \begin{tabularx}{\textwidth}{|*{32}{@{}B@{}|}}
    \hline
    31 & 30 & 29 & 28 & 27 & 26 & 25 & 24 & 23 & 22 & 21 & 20 & 19 &
    18 & 17 & 16 & 15 & 14 & 13 & 12 & 11 & 10 & 9 & 8 & 7 & 6 & 5 &
    4 & 3 & 2 & 1 & 0 \\
    \hline
    \multicolumn{1}{|@{}c@{}|}{C} &
    \multicolumn{1}{@{}c@{}|}{N} &
    \multicolumn{1}{@{}c@{}|}{Z} &
    \multicolumn{1}{@{}c@{}|}{P} &
    \multicolumn{6}{l|}{Opcode} &
    \multicolumn{22}{l|}{\textit{Operands}} \\
    \hline
  \end{tabularx}
  \caption{Instruction encoding}
  \label{fig:instruction-encoding}
\end{figure}

The rest of the instruction is used for operands. Registers are always
referenced by a 5-bit register number. Signed immediate values have a
sign bit in the most significant position, with 1 indicating a
negative value. The specific encoding depends upon the addressing
mode; these encodings are shown in figure \ref{fig:operand-encodings}.

\begin{figure}[h]
  \renewcommand{\arraystretch}{1.2}
  \centering
  \begin{tabularx}{\textwidth}{c|*{23}{@{}B@{}|}}
    \cline{2-23}
    & 21 & 20 & 19 & 18 & 17 & 16 & 15 & 14 & 13 & 12 & 11 & 10 & 9 &
    8 & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0 \\
    \hline
    \multicolumn{1}{|r|}{RD} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{dest}}} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{x}}} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{y}}} &
    \multicolumn{7}{l|}{\textit{Unused}} \\
    \hline
    \multicolumn{1}{|r|}{RI} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{dest}}} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{x}}} &
    \multicolumn{12}{l|}{
      \texttt{I\textsubscript{y}} (Signed 12-bit immediate)} \\
    \hline
    \multicolumn{1}{|r|}{BO} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{target}}} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{base}}} &
    \multicolumn{12}{l|}{
      \texttt{I\textsubscript{offset}} (Unsigned 12-bit immediate)} \\
    \hline
    \multicolumn{1}{|r|}{BI} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{target}}} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{base}}} &
    \multicolumn{5}{l|}{\texttt{R\textsubscript{index}}} &
    \multicolumn{7}{l|}{\textit{Unused}} \\
    \hline
    \multicolumn{1}{|r|}{I} &
    \multicolumn{22}{l|}{\texttt{I} (Signed 22-bit immediate)} \\
    \hline
  \end{tabularx}
  \caption{Operand encodings for the different address modes}
  \label{fig:operand-encodings}
\end{figure}

\end{document}
