% $Id: float_srm.tex,v 1.14 2023/11/14 05:13:37 leavens Exp leavens $
\documentclass[11pt,letterpaper]{article}
\usepackage[T1]{fontenc}
\usepackage{times}
\usepackage{textcomp} %required to set upquote flag and for luximono
%\usepackage[scaled=0.81]{luximono}
\usepackage{enumitem}
\usepackage{listings}
\usepackage{graphics}
\usepackage{color}
\usepackage{ragged2e}
\lstset{language=C,basicstyle=\ttfamily,commentstyle=\rmfamily\itshape}
\lstset{morecomment=[l]{//}, %use comment-line-style!
        morecomment=[s]{/*}{*/}} %for multiline comments
\lstset{upquote=true} %FH
% The following is needed for C programs
\lstset{showspaces=false,showstringspaces=false}
%\lstset{mathescape=true}
\input{boxed-figure-new}
% getting files for figures
\newcommand{\LSTFILE}[1]{
\lstinputlisting[basicstyle=\small\ttfamily]{#1}
}
\newcommand{\LSTFILESLICE}[2]{
\lstinputlisting[basicstyle=\small\ttfamily,linerange={#1}]{#2}
}
%
\newcommand{\LSTCFILE}[1]{
\lstinputlisting[language=C,basicstyle=\small\ttfamily]{#1}
}
\newcommand{\LSTCFILESLICE}[2]{
\lstinputlisting[language=C,basicstyle=\small\ttfamily,linerange={#1}]{#2}
}
\usepackage[bookmarks=false]{hyperref}
%\usepackage{varioref}  % doesn't work with hyperref, it seems, sigh
%\renewcommand{\reftextfacebefore}{on the previous page}
%\renewcommand{\reftextfaceafter}{on the next page}
\newcommand{\tabref}[1]{Table~\ref{#1}}  % vref from varioref
\newcommand{\tabnref}[1]{Table~\ref{#1}}  % doesn't use varioref
\newcommand{\figref}[1]{Figure~\ref{#1}}  % vref from varioref
\newcommand{\fignref}[1]{Figure~\ref{#1}}  % doesn't use varioref
\newcommand{\secref}[1]{Section~\ref{#1}}  % vref from varioref
\newcommand{\secnref}[1]{Section~\ref{#1}}  % doesn't use varioref

\input{obey}
\input{grammar}
\renewcommand{\nonterm}[1]{\mbox{$\langle$\textrm{#1}$\rangle$}}
\renewcommand{\arbno}[1]{\{#1\}}
\newcommand{\gramquote}[1]{\textrm{`}#1\textrm{'}}
\input{use-full-height}
\input{use-full-width}
\input{continuedenum}

\setlength\RaggedRightParindent{\parindent}
\input{float_srm-isa.tex}
\newcommand{\IFO}[2]{\textrm{\textbf{if} \ensuremath{#1} \textbf{then} \ensuremath{#2} }}
\newcommand{\IF}[3]{\textrm{\textbf{if} #1 \textbf{then} #2 \textbf{else} #3}}
\newcommand{\EQUALS}{\ensuremath{=}} % or {\ensuremath{\:\texttt{==}\:}}
%
\bibliographystyle{plain}
%
\title{Floating Point Simplified RISC Machine Manual \\
       (\lstinline!$Revision: 1.14 $!)}
\author{Gary T. Leavens \\
        Leavens@ucf.edu}
\begin{document}

\maketitle
\begin{abstract}
This document defines the machine code of the Floating Point Simplified RISC Machine VM for
use (as an example) in the Systems Software class (COP 3402) at UCF.
\end{abstract}

\section{Overview}

The Floating Point Simplified RISC Machine (FPSRM) processor's
instruction set architecture (ISA) is based on the MIPS processor's ISA
\cite{Kane-Heinrich92}, but adapted to work with (single-precision)
float-point numbers as well as integers.
In particular, FPSRM is a little-endian machine with
$\WS$-bit ($\WSinBytes$-byte) words.
All instructions are also $\WS$-bits wide and there is no virtual
memory support, kernel mode support, or other advanced features.

\subsection{Inputs and Outputs}

\subsubsection{Binary Object Files}

The VM is passed a single file name on its command line as an
argument; optionally it may also get the option \texttt{-p} as an argument.
When given a \texttt{-p} argument followed by a binary object file
name, the VM loads the binary object file and prints the assembly
language form of the program, see \secref{sec:printing} details.
The remainder of this section is concerned
with what the VM does when it only is given a binary object file name
on its command line as an argument.

The file name given to the VM must be the name of a (readable)
binary object file containing the program that the VM should execute.
For example, if the VM's executable is named \texttt{vm} and the program it
should run is contained in the file named \texttt{test.bof}
(and both these files are in the current directory), then the VM should
execute the program in the file \texttt{test.bof} by executing
the following command in the Unix shell.

\begin{lstlisting}
  ./vm test.bof
\end{lstlisting}

The format of a binary object file (BOF) is given in the header file
\texttt{bof.h}, which is shown in part in \figref{fig:bofh}.
A BOF starts the header, then the instructions (also in
binary form) follow, followed by the initial values of data.
This layout of binary object files is shown in \figref{fig:boffilelayout}.

The header of a binary object file starts with a 4-character field
that contains the characters ``\lstinline!BOF!''
(and a null character); this kind of ``magic number'' is commonly used
to identify files in Unix.
The magic number is followed (in the BOF header) by the starting address of
the program's code and the length of the program's code (in bytes), which
constitutes the ``text'' section of the binary object file.
These are followed by the starting address of the data section and its
length (in bytes).
The data section contains the global/static variables that the program uses.
Finally, the header contains the initial value for the stack and frame
pointers, which is the address (in bytes) of the bottom of the runtime
stack.

\begin{figure}[htbp]
\LSTCFILESLICE{1-24,75-76}{bof.h}
\caption{The \texttt{bof.h} header file that defines the format and
  operations for binary object files.}
\label{fig:bofh}
\end{figure}

\begin{figure}[htbp]
\includegraphics*{BOF_layout.png}
\caption{The layout of a binary object file.}
\label{fig:boffilelayout}
\end{figure}

\subsubsection{Initial/Default Values}
\label{sec:initial}

The memory of the machine starts at all zero ($0$) values (i.e., all
bits are $0$).
Then the instructions specified by the given binary object file
(as named on the command line) are loaded into memory,
starting at address $0$, making the contents of the first $N$ bytes
(where $N$ is divisible by $\WSinBytes$) 
of memory be the same as the $N$ bytes following the header itself in
the binary object file; here $N$ is the same as the header's value of
the \lstinline!text_length! field.
Following those $N$ bytes are the bytes of the data section.
These are loaded into the memory starting at the data start address
given in the header; thus any initial values are copied from the
data section of the binary object file into VM's memory.

When the program starts executing:
\begin{itemize}
\item
the register {\GP} is set to the start address of the data section
given in the header,
which must be divisible by $\WSinBytes$,

\item
the registers {\FP} and {\SP} are both is set to the stack bottom
address given in the header, which must be divisible by $\WSinBytes$
and strictly greater than the start address of the data section, and

\item
the program counter {\PC} is set to the text section's start address,
which must be divisible by $\WSinBytes$ and strictly less than the
data section's start address.
\end{itemize}

% \clearpage

\subsection{The Running Program's Input and Output}

When the program executes instructions to read or write characters,
these are read from standard input (\texttt{stdin}) and written to
standard output (\texttt{stdout}).

However, note that if you want the program to read a character, typing a single
character (say \texttt{x}) into the terminal (i.e., to the shell) 
while the program is running will not send that character immediately
to the program, as standard input is buffered by default.  To send
characters to the program it is best to use a pipe or file redirection
in the Unix shell; for example, to send the two characters \texttt{x}
and \texttt{y} (followed by a newline character)
to the VM running the program \texttt{progfile.bof} one
could use the following command at the Unix shell:

\begin{lstlisting}
  echo xy | ./vm progfile.bof
\end{lstlisting}

Another command that would accomplish the same thing is to put the
characters to be input into a file (using a text editor), say
\texttt{xy-input.txt} and then to use the following Unix command.

\begin{lstlisting}
  ./vm progfile.bof < xy-input.txt
\end{lstlisting}

\subsection{Tracing Output}

By default, the VM produces output that traces the VM's execution on
\texttt{stdout}.
This tracing output can be
turned off by executing a \texttt{NOTR} system call instruction
and can be turned on by executing a \texttt{STRA} system call
instruction.\footnote{The \texttt{STRA} instruction has no effect if
the VM is already producing tracing output.}
(See \secref{sec:syscall} for more information about these system call
instructions.)

The tracing output shows the initial state of the VM, then for each
instruction executed, it shows the address (in bytes) of that
instruction and then the assembly language form of that instruction.

The state of the machine shown in tracing output shows:
the values in the PC, the values of the HI and LO registers (if those
are not zero) and the values in all the general purpose registers,
then the memory starting at the address in $\GPR{\GP}$
with locations containing zeros only indicated with ``\texttt{...}''.
and then the data between the addresses between $\GPR{\SP}$ and
the stack bottom address specified in the binary object file.
The idea is that those addresses should include the runtime stack.
When showing the memory, locations containing zeros are only
indicated with ``\texttt{...}''.
For example, when the binary object file that is assembled from the
assembly code shown in \figref{fig:test0asm} is executed,
which is found in the file \texttt{vm\_test0.bof},
it produces the output shown in \figref{fig:test0output}.

\begin{figure}
\LSTFILE{vm_test0.asm}
\caption{The FPSRM assembly language file \texttt{vm\_test0.asm}.} 
\label{fig:test0asm}
\end{figure}

\begin{figure}
\lstinputlisting[basicstyle=\ttfamily\scriptsize]{vm_test0.out}
\caption{The output of running the VM on file \texttt{vm\_test0.bof}
  (which is the result of using the assembler on \texttt{vm\_test0.asm}),
  with the command \texttt{./vm vm\_test0.bof},
  as would be printed on standard output.} 
\label{fig:test0output}
\end{figure}

\subsection{Printing the Program}
\label{sec:printing}

When the VM is given the argument \texttt{-p} option followed by a
binary object file name, it first loads the instructions and data from the
given binary object file, then it prints what was loaded in assembly
language format, and then the VM exits (without running the program). This
can be helpful for understanding what a program is doing. This output
is shown in \figref{fig:test0listing}.

\begin{figure}
\LSTFILE{vm_test0.lst}
\caption{The output of running \texttt{./vm -p vm\_test0.bof}. 
  (where the file \texttt{vm\_test0.bof} is the result of assembling the file
  \texttt{vm\_test0.asm} that is shown in \figref{fig:test0asm}).} 
\label{fig:test0listing}
\end{figure}

\subsection{Error Outputs}

All error messages (e.g., for division by zero) are sent to
standard error output (\texttt{stderr}).

\subsection{Exit Code}

When the machine halts normally, it exits with a zero error code
(which indicates success on Unix).  However, when the machine
encounters an error it halts and exits with a non-zero exit code
(which indicates failure on Unix).

\section{Architecture}

In FPSRM, words are $\WS$ bits ($\WSinBytes$ bytes).
These bits can be interpreted as a floating-point number, integer, Boolean,
or as an address.
The machine is byte addressed but instructions must always be at an
address that is on a word boundary (i.e., whose address is evenly
divisible by $\WSinBytes$).

There are separate instructions for manipulating floating-point
numbers, which allows an implementation of the FPSRM to track what
kind of data is in each word, as that could be useful for tracing.

\subsection{Registers}

\subsubsection{General Purpose Registers and Their Names}

The FPSRM is a register machine with 32
general purpose registers\footnote{What we call
``registers'' in this document are simply important concepts that
simulate what would be registers in a hardware implementation of the
virtual machine. For the VM program, these registers would be implemented
as variables.},
numbered 0 to 31 (inclusive).
These are all $\WS$-bit registers.
Since there are 32 registers,
instructions use $\LOGofRegs$ bits to specify them.

Register 0 cannot be written to, and when read its value is always 0.

Conventions (from the MIPS architecture \cite{Kane-Heinrich92}) are
followed for these registers and their names,
as shown in \tabref{tab:registers}.
The names shown in \tabnref{tab:registers} are conventional ones.

\begin{table}[htb]
  \caption{FPSRM Register Numbers, Use, and Names}
  \label{tab:registers}
\begin{center}
\begin{tabular}{| l | l | l |}
  \hline
  Number & Use & Name\\
  \hline
  $0$ & always 0 (can't write to this register!) & \\
  $1$ & assembler temporary & \NAMEDREG{at} \\
  $2-3$ & function results & \NAMEDREG{v0}, \NAMEDREG{v1} \\
  $4-7$ & function arguments & \NAMEDREG{a0}$-$\NAMEDREG{a3} \\
  $8-15$ & temporaries & \NAMEDREG{t0}$-$\NAMEDREG{t7} \\
  $16-23$ & temporaries & \NAMEDREG{s0}$-$\NAMEDREG{s7} \\
  $24-25$ & temporaries & \NAMEDREG{t8}, \NAMEDREG{t9} \\
  $26-27$ & reserved for use by OS (don't use!) & \\
  $28$ & globals pointer & $\GP$ \\
  $29$ & stack pointer & $\SP$ \\
  $30$ & frame pointer & $\FP$ \\
  $31$ & return address & $\RA$ \\
  \hline
\end{tabular}
\end{center}
\end{table}

\subsubsection{Special Purpose Registers}

FPSRM also has a few special registers. The registers are named:

\begin{itemize}
\item
  {\PC}, the program counter which holds the (byte) address of the next
  instruction to execute,

\item
  {\HI}, the high part (i.e., most significant bits) of the result of
  an integer multiplication or the remainder in an integer division,

\item
  {\LO}, the low part (i.e., least significant bits) of the result of
  an integer multiplication or the quotient in an integer division.
\end{itemize}

The $\PC$ register is manipulated by jump instructions.
The $\HI$ and $\LO$ registers are read by instructions that move their
contents into another register.

The registers that normally hold addresses ($\GP$, $\SP$, $\FP$,
$\RA$) should not have floating-point numbers stored into them and
their contents should not be manipulated as floating-point numbers.

\subsubsection{Calling Convention}

The calling convention on the FPSRM follows the calling convention on
the MIPS processor.

That is, the caller must save registers $1-15$, and $24-25$
if they will be needed after a call (and then restores them when
needed).

The callee saves (and restores before it returns) registers $16-23$
and $29-31$, if it uses (writes) them.

(Furthermore, register $0$ cannot be changed and registers $1$ and
$28$ should not be changed by a hand-written routine.
Registers $26-27$ are reserved for the OS should not be changed by user code.)

Note that the jump-and-link (\texttt{JAL}) instruction
does not save any registers except the $\PC$,
and it will save that in register $31$.

\subsection{Binary Instruction Format}

In object code,
all instructions are one word long and start with a 6-bit opcode.
However, instructions may have one of several formats, with the format
depending on the opcode (called ``op'' below).
The fields of each instruction format shown in \tabref{tab:instrfmts}
are followed by their width in bits;
for example the op field is 6 bits wide.

\begin{table}[htb]
  \caption{FPSRM Instruction Formats}
  \label{tab:instrfmts}
\begin{itemize}
\item Register/computational type instruction format: \\
\begin{tabular}{|c|p{6ex}{c}|p{6ex}{c}|p{6ex}{c}|p{10ex}|p{9ex}|}
  \hline
  op:6 & \multicolumn{1}{|c|}{rs:5} & \multicolumn{1}{|c|}{rt:5} & \multicolumn{1}{|c|}{rd:5} & \multicolumn{1}{|c|}{shift:5} & \multicolumn{1}{|c|}{func:6} \\
  \hline
\end{tabular}

\item System call instructions, whose format is a variant of the register type
instruction format, but with a func field value of 12: \\
\begin{tabular}{|c|p{6ex}{c}|p{6ex}{c}|p{6ex}{c}|p{10ex}|p{9ex}|}
  \hline
  op:6 & \multicolumn{4}{|c|}{~~~~~~~~~~~~~code:20~~~~~~~~~~~~~~~~} & \multicolumn{1}{|c|}{func:6} \\
  \hline
\end{tabular}

\item
Immediate operand type instruction format: \\
\begin{tabular}{| c | p{6ex}{c} | p{6ex}{c} | p{16ex} |}
  \hline
  op:6 & \multicolumn{1}{|c|}{rs:5} & \multicolumn{1}{|c|}{rt:5} & \multicolumn{1}{c|}{~~~~~~~~~immed:16~~~~~~~~~~~} \\
  \hline
\end{tabular}

\item
Jump type instruction format: \\
\begin{tabular}{| c | p{26ex}|}
  \hline
  op:6 & \multicolumn{1}{c|}{~~~~~~~~~~~~~~~~~~~~~addr:26~~~~~~~~~~~~~~~~~~~~~~~} \\
  \hline
\end{tabular}
\end{itemize}
\end{table}

The list of instructions and details on their execution appears in
Appendix \ref{appsec:A}.

\subsection{Machine Cycles}

The FPSRM instruction cycle conceptually does the following for each
instruction:

\begin{enumerate}
\item
  Let $\IR$ be the instruction at the location that {\PC} indicates.
  (Note that $\IR$ could be considered to be the contents of a register.)

\item
  The {\PC} is made to point to the next instruction
  (i.e., it is set to the address $\PC + \WSinBytes$).

\item
  Then the instruction in $\IR$ is executed.
  The op component of this instruction ($\IR$.op) indicates the operation
  to be executed.
  For example, if $\IR$.op encodes the instruction JR,
  then the machine jumps to address given the register argument, by
  setting the $\PC$ register (to the contents of the given register).
\end{enumerate}

\subsection{Size Limits}

The following constant (found in \texttt{machine.h}) defines the size of the memory for the VM.

\LSTCFILESLICE{10-10}{machine.h}

Note that \lstinline!BYTES_PER_WORD! is defined to be 4.
% in \lstinline!machine_types.h!.

\subsection{Invariants}

The VM enforces the following invariants and will halt with an error
message (written to stderr) if one of them is violated. In these
invariants the registers are all treated as holding (byte) addrresses.

\newcommand{\BPW}{\mbox{\texttt{BYTES\_PER\_WORD}}}
\begin{itemize}
\item
  $\PC \MOD \BPW = 0$,

\item
  $\GPR{\GP} \MOD \BPW = 0$,

\item
  $\GPR{\SP} \MOD \BPW = 0$,

\item
  $\GPR{\FP} \MOD \BPW = 0$,

\item
  $0 \leq \GPR{\GP}$,

\item
  $\GPR{\GP} < \GPR{\SP}$,

\item
  $\GPR{\SP} \leq \GPR{\FP}$,

\item
  $\GPR{\FP} < \mbox{\texttt{MEMORY\_SIZE\_IN\_BYTES}}$,
   
\item
  $0 \leq \PC$, 

\item
  $\PC < \mbox{\texttt{MEMORY\_SIZE\_IN\_BYTES}}$, and

\item
  $\GPR{0} = 0$.
\end{itemize}

\appendix
\section{Appendix A}
\label{appsec:A}

In the following tables, italicized names (such as $s$) are
meta-variables that refer to integers.
If an instruction's field is
notated as $-$, then its value does not matter (we use $0$ as a
placeholder for such values in examples).

All numbers appearing in the following table are in decimal (base 10) notation.

\subsection{Register/Computational Instructions}

Note that all of the instructions in table \tabref{tab:rformatinstrs}
have an opcode of $0$,
and a function specified by the func field. They each also have 3 register
arguments: rs, rt, and rd.
The contents of the general purpose register $r$ is
notated as $\GPR{r}$ in the table.
All numbers in the table are in decimal notation.

Floating-point arithmetic operations are performed as for C
\textbf{float} values.
Integer arithmetic, bitwise, and logical operations are performed as for C
\textbf{int} values.
However, the right shift works on the contents of the register
$\GPR{t}$ in a logical manner, as if it were an \textbf{unsigned int},
so it should shift in zeros from the left.

\begin{table}[htbp]
\caption{Register Format Instructions}
\label{tab:rformatinstrs}
\begin{tabular}{|l|l|c|c|c|c|l|p{9cm}|}
\hline
~       & ~  & ~  & ~  & ~  & ~     &      & Comment \\
Name    & op & rs & rt & rd & shift & func & (Explanation) \\
\hline
ADD     & 0  &$s$ &$t$ &$d$  & -    & 33 & Integer Add: $\GPR{d} \GETS \GPR{s} + \GPR{t}$ \\
\hline
FADD     & 0  &$s$ &$t$ &$d$  & -   & 49 & Floating-point Add: $\GPR{d} \GETS \GPR{s} + \GPR{t}$ \\
\hline
SUB     & 0  &$s$ &$t$ &$d$  & -    & 35 & Integer Subtract: $\GPR{d} \GETS \GPR{s} - \GPR{t}$ \\
\hline
FSUB     & 0  &$s$ &$t$ &$d$ & -    & 51 & Floating-point Subtract: $\GPR{d} \GETS \GPR{s} - \GPR{t}$ \\
\hline
MUL     & 0  &$s$ &$t$ & -    & -  & 25 & Integer Multiply: Multiply
$\GPR{s}$ and $\GPR{t}$, \\
& & & & & & & putting the least significant bits in $\LO$ \\
& & & & & & & and the most significant bits in $\HI$. \\
& & & & & & & $(\HI,\LO) \GETS \GPR{s} \times \GPR{t}$ \\
\hline
FMUL     & 0  &$s$ &$t$ &$d$ & -    & 41 & Floating-point Multiply: $\GPR{d} \GETS \GPR{s} \times \GPR{t}$ \\
\hline
DIV     & 0  &$s$ &$t$ & -   & -    & 27 & Integer Divide (remainder in $\HI$, quotient in $\LO$): \\
        &    &    &    &     &      &    & $\HI \GETS \GPR{s} \MOD \GPR{t}$ \\
        &    &    &    &     &      &    & $\LO \GETS \GPR{s} / \GPR{t})$ \\
\hline
FDIV     & 0  &$s$ &$t$ &$d$ & -    & 43 & Floating-point Divide: $\GPR{d} \GETS \GPR{s} / \GPR{t}$ \\
\hline
MFHI    & 0  & -  & -  & $d$ & -    & 16 & Move from HI: $\GPR{d} \GETS \HI$ \\
\hline
MFLO    & 0  & -  & -  & $d$ & -    & 18 & Move from LO: $\GPR{d} \GETS \LO$ \\
\hline
AND     &  0  &$s$ &$t$ & $d$ & -    & 36 & Bitwise And: $\GPR{d} \GETS \GPR{s} \AND \GPR{t}$ \\
\hline
BOR     &  0  &$s$ &$t$ & $d$ & -    & 37 & Bitwise Or: $\GPR{d} \GETS \GPR{s} \OR \GPR{t}$ \\
\hline
NOR     &  0  &$s$ &$t$ & $d$ & -    & 39 & Bitwise Not-Or: $\GPR{d} \GETS \neg(\GPR{s} \OR \GPR{t})$ \\
\hline
XOR     &  0  &$s$ &$t$ & $d$ & -    & 38 & Bitwise Exclusive-Or: $\GPR{d} \GETS \GPR{s} \XOR \GPR{t}$ \\
\hline
SLL     &  0  & - &$t$ & $d$ & $h$  & 0 & Shift Left Logical: $\GPR{d} \GETS \GPR{t} \LSHIFT h$ \\
\hline
SRL     &  0  & - &$t$ & $d$ & $h$  & 3 & Shift Right Logical: $\GPR{d} \GETS \GPR{t} \RSHIFT h$ \\
\hline
CVT     &  0 & -  &$t$ & $d$ & -    & 4 & Convert to Float: $\GPR{d} \GETS \texttt{(float)} \GPR{t}$ \\
\hline
RND     &  0 & -  &$t$ & $d$ & -    & 5 & Round to Integer: $\GPR{d} \GETS $\texttt{round($\GPR{t}$)} \\
\hline
JR      &  0  &$s$ & 0 &  0  &  0   & 8 & Jump Register: $\PC \GETS \GPR{s}$ \\
\hline
SYSCALL &  0  & -  & - & -   & -   & 12 & System Call: (see \tabref{tab:syscalls}) \\
\hline
\end{tabular}
\end{table}

\newpage

\subsection{Immediate Type Instructions}

The instructions in \tabref{tab:immedinstrs} may have up to 2 register
arguments, and all have an immediate operand, which is a 16 bit
integer value.

For arithmetic operations, the immediate value is sign-extended (to a 32-bit
\textbf{int} value),
which is written in the explanations using the function ``{\SIGNEXTENDNAME}.'' 
For example, suppose $i$ is $-1$, which is FFFF in hexadecimal
notation;
then $\SIGNEXTEND{i}$ is FFFFFFFF in hexadecimal, which still
represents $-1$.

However, for logical operations, the immediate value is zero-extended,
which is written in the explanations using the function ``{\ZEROEXTENDNAME}.''
For example, suppose $i$ is $-1$, which is FFFF in hexadecimal
notation;
then $\ZEROEXTEND{i}$ is 0000FFFF in hexadecimal notation.

The branch instructions BEQ, BGEZ, BGTZ, BLEZ, BLTZ, and BNEQ all
treat their register argument as if it were an integer value.
However, the branch instructions BFEQ, BFGEZ, BFGTZ, BFLEZ, BFLTZ, and
BFNEQ all treat their register argument as if it were a floating-point value.

For the branch instructions, the immediate value, $o$ is first shifted left 2
bits (multiplied by 4) and then sign-extended, which is written as
``{\FORMOFFSETNAME}'' in the table.
(Thus $\FORMOFFSET{o} = \SIGNEXTEND{4 \times o}$.)
Note that the resulting address is added to the address of the
instruction following the currently executing instruction, not the
address of the instruction itself, since the $\PC$ has already been advanced.

For loads and stores, $\MEMORY{a}$ denotes the contents of the
machine's memory at the byte address $a$.

\begin{table}[htbp]
\caption{Immediate format instructions:}
\label{tab:immedinstrs}  
\begin{tabular}{|l|r|c|c|c|p{11cm}|}
\hline
~    &      & ~  & ~  & ~     & Comment \\
Name & op   & rs & rt & immed & (Explanation) \\
\hline
ADDI  & 9   &$s$ &$t$ & $i$ & Add immediate: $\GPR{t} \GETS \GPR{s} + \SIGNEXTEND{i}$ \\
\hline
ANDI & 12    &$s$ &$t$ & $i$ & Bitwise And immediate: $\GPR{t} \GETS \GPR{s} \AND \ZEROEXTEND{i}$ \\
\hline
BORI & 13    &$s$ &$t$ & $i$ & Bitwise Or immediate: $\GPR{t} \GETS \GPR{s} \OR \ZEROEXTEND{i}$ \\
\hline
XORI & 14    &$s$ &$t$ & $i$ & Bitwise Xor immediate: $\GPR{t} \GETS \GPR{s} \XOR \ZEROEXTEND{i}$ \\
\hline
BEQ & 4     &$s$ &$t$ & $o$ & Branch on Equal: $\IFO{\GPR{s} = \GPR{t}}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BGEZ & 1    &$s$ & 1  & $o$ & Branch $\geq$ 0: $\IFO{\GPR{s} \geq 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BGTZ & 7    &$s$ & 0  & $o$ & Branch $>$ 0: $\IFO{\GPR{s} > 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BLEZ & 6    &$s$ & 0  & $o$ & Branch $\leq$ 0: $\IFO{\GPR{s} \leq 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BLTZ & 8    &$s$ & 0  & $o$ & Branch $<$ 0: $\IFO{\GPR{s} < 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BNE  & 5    &$s$ &$t$ & $o$ & Branch Not Equal: $\IFO{\GPR{s} \neq \GPR{t}}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BFEQ & 20     &$s$ &$t$ & $o$ & Branch Float Equal: $\IFO{\GPR{s} = \GPR{t}}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BFGEZ & 17    &$s$ & 1  & $o$ & Branch Float $\geq$ 0: $\IFO{\GPR{s} \geq 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BFGTZ & 23    &$s$ & 0  & $o$ & Branch Float $>$ 0: $\IFO{\GPR{s} > 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BFLEZ & 22    &$s$ & 0  & $o$ & Branch Float $\leq$ 0: $\IFO{\GPR{s} \leq 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BFLTZ & 24    &$s$ & 0  & $o$ & Branch Float $<$ 0: $\IFO{\GPR{s} < 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
BFNE  & 21    &$s$ &$t$ & $o$ & Branch Float Not Equal: $\IFO{\GPR{s} \neq \GPR{t}}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\
\hline
LBU  & 36   &$b$ &$t$ & $o$ & Load Byte Unsigned: \\
     &      &    &    &     & $\GPR{t} \GETS \ZEROEXTEND{\MEMORY{\GPR{b} + \FORMOFFSET{o}}}$ \\
\hline
LW   & 35   &$b$ &$t$ & $o$ & Load Word ($\WSinBytes$ bytes): \\
     &      &    &    &     & $\GPR{t} \GETS \MEMORY{\GPR{b} + \FORMOFFSET{o}}$ \\
\hline
FLW   & 41   &$b$ &$t$ & $o$ & Load Word Float: \\
     &      &    &    &     & $\GPR{t} \GETS \MEMORY{\GPR{b} + \FORMOFFSET{o}}$ \\
\hline
SB   & 40   &$b$ &$t$ & $o$ & Store Byte (least significant byte of $\GPR{t}$): \\
     &      &    &    &     & $\MEMORY{\GPR{b} + \FORMOFFSET{o}} \GETS \GPR{t}$ \\
\hline
SW   & 43   &$b$ &$t$ & $o$ & Store Word ($\WSinBytes$ bytes): \\
     &      &    &    &     & $\MEMORY{\GPR{b} + \FORMOFFSET{o}} \GETS \GPR{t}$ \\
\hline
FSW  & 42   &$b$ &$t$ & $o$ & Store Word Float: \\
     &      &    &    &     & $\MEMORY{\GPR{b} + \FORMOFFSET{o}} \GETS \GPR{t}$ \\
\hline
\end{tabular}
\end{table}

\subsection{Jump Type Instructions}

The instructions in \tabref{tab:jumpinstrs} have a $\WSminusOP$-bit field ``addr''
which is used to form the address to jump to.
Forming this address is done by left-shifting the given ``addr''
field, $a$, by 2 bits,
and then concatenating the (4) high bits of the $\PC$ with those
$\WSminusOP+2$ bits to form a $\WS$-bit address.
This is written ``$\FORMADDRESS{\PC,a}$'' in the table.
For example if $a$ is DECADE in hexadecimal notation, and $\PC$ is
FFFACADE in hexadecimal notation, then $\FORMADDRESS{\PC}{a}$ is F37B2B78
in hexadecimal notation. (Note: if the high-order 4 bits of $\PC$
are 0, then $\FORMADDRESS{PC}{a}$ is equivalent to left-shifting $a$
by 2 bits.)

\begin{table}[htbp]
\caption{Jump Type Instructions}
\label{tab:jumpinstrs}  
\begin{tabular}{|r|l|l|p{11cm}|}
\hline
~      & ~  & ~    & Comment \\
Name   & op & addr & (Explanation) \\
\hline
JMP    & 2  & a    & Jump: $\PC \GETS \FORMADDRESS{PC}{a}$ \\
\hline
JAL    & 3  & a    & Jump and Link: $\GPR{\RA} \GETS \PC; \PC \GETS \FORMADDRESS{\PC}{a}$ \\
\hline
\end{tabular}
\end{table}

The Jump and Link (JAL) instruction does a subroutine call. It does
not explicitly manipulate the runtime stack.
% [[[Put more in about calling conventions here.]]]

\subsection{System Calls}
\label{sec:syscall}

System calls are used to provide operating system services.
System calls are made by instructions with op 0 and func 12 having the
following format (with code field made of the 20 bits of what would
be the rs, rt, rd, and shift fields of a register type instruction,
all combined).
The code field is used to specify the service requested.

System calls include exiting a program and various kinds of printing
and reading of character data (bytes).
These are described in \tabref{tab:syscalls},
using C library equivalents.
In the table, an entry of $-$ means that the contents of argument registers 
is not specified.
Otherwise, the contents of particular argument registers are used to
pass actual arguments to the system calls (the program must load the
actual argument values into those registers before making the call).
Only the PFLT system call treats its argument (in {\AZERO}) as a
floating-point number.
(Recall that the correspondence between named registers and register
numbers is given in \tabref{tab:registers}.)
All printing done by these instructions
is to the VM's standard output (stdout) and
reading is from the VM's standard input (stdin).

\begin{table}[htbp]
\caption{System Calls}
\label{tab:syscalls}
\begin{tabular}{|l|l|l|l|}
\hline
code & name  & arg. reg. & Effect (in terms of C std. library) \\
\hline
10   & EXIT  & - & \texttt{exit(0) // halt} \\
\hline
 4   & PSTR  & \AZERO & $\GPR{\VZERO} \GETS $ \texttt{printf("\%s",\&$\MEMORY{\GPR{\AZERO}}$)} \\
\hline
 5   & PINT  & \AZERO & $\GPR{\VZERO} \GETS $ \texttt{printf("\%d",\GPR{\AZERO})} \\
\hline
 6   & PFLT  & \AZERO & $\GPR{\VZERO} \GETS $ \texttt{printf("\%f",\GPR{\AZERO})} \\
\hline
11   & PCH   & \AZERO & $\GPR{\VZERO} \GETS $\texttt{fputc($\GPR{\AZERO}$,stdout)} \\
\hline
12   & RCH   & -    & $\GPR{\VZERO} \GETS $ \texttt{getc(stdin)} \\
\hline
\hline
13   & RFLT  & -    & \texttt{\textbf{float}}~\texttt{f;} \texttt{fscanf(stdin,"\%f",\&f);}
                      $\GPR{\VZERO} \GETS $ \texttt{f} \\
\hline
256   & STRA & -  & \textrm{start VM tracing; start tracing output} \\
\hline
257   & NOTR & -  & \textrm{no VM tracing; stop the tracing output} \\
\hline
\end{tabular}
\end{table}

Implementing the PSTR instruction is a bit tricky, because 
the \texttt{printf} function from the C standard library function
will expect a C pointer to characters as its
argument, but that can be given to it by giving it
the address of those character's representations
in the memory starting at the VM address given by the
contents of $\GPR{\AZERO}$.
A similar trick can be used for RFLT, but the code snippet given in 
\tabref{tab:syscalls} will also work.

\bibliography{float_srm.bib}

\end{document}
