\section{The SUIFvm instruction set}

Here is a description of the SUIFvm instructions.  Readers familiar with
SUIF 1 and \emph{The SUIF Library Reference Manual} that documents it
will recognize most of these descriptions.

\begin{itemize}
\item{[[NOP]].\ \ } Do nothing at all.  All of the operands for these
     instructions should be null.

\item{[[LDA]].\ \ } Move the address (not the dereferenced value) specified
     by the source operand into the destination.

\item{[[LDC]].\ \ } Move a constant value (the source operand) into the
     destination.

\item{[[LOD]].\ \ }
     Load the value at the address contained in the source operand
     into the destination operand.

\item{[[STR]].\ \ }
     Store the value in the source operand at the address contained in
     the destination operand.

\item{[[MEMCPY]].\ \ }
     Memory to memory copy.  Load the value from the address in the
     source operand and store it at the address in the destination operand.

\item{[[MOV]].\ \ }
     Copy the value of the source operand to the destination operand.

\item{[[CVT]].\ \ }
     Convert the source operand to the destination type and put it in the
     destination operand.

\item{[[NEG]].\ \ }
     Negation.  Change the sign of the value in the source operand and
     put the result in the destination operand.

\item{[[ADD]].\ \ }
     Add the values in the first two source operands and put the
     result in the destination.

\item{[[SUB]].\ \ }
     Subtract the value in the second operand from the value in the
     first source and put the result in the destination.

\item{[[MUL]], [[DIV]].\ \ }
     Multiply or divide the value in the first source operand by the value in
     the second operand and put the result in the destination.

\item{[[REM]], [[MOD]].\ \ }
     Remainder and modulus.  These two instructions are very similar.
     Both divide the value in the first source operand by the value in the
     second operand to find the remainder or modulus.  The [[rem]]
     instruction is identical to the modulus operator in ANSI C.  That
     is, if either source operand is negative, the sign of the result is
     undefined and depends on the semantics of integer division.  The
     [[mod]] instruction is the same except that its result is always
     guaranteed to be positive.

\item{[[NOT]].\ \ }
     Bit-wise inversion.  Compute the one's complement negation of the
     value in the source operand and put the result in the destination.

\item{[[AND]], [[IOR]], [[XOR]].\ \ }
     Compute the bit-wise [[and]], inclusive [[or]], or exclusive [[or]] of the
     values in the first two source operands and put the result in the
     destination.

\item{[[ASR]], [[LSR]].\ \ }
     Shift the value in the first source operand right by the amount
     specified in the second operand.  [[asr]] performs sign extension;
     [[lsr]] does not.

\item{[[LSL]].\ \ }
     Shift the value in the first source operand left by the amount
     specified in the second operand.

\item{[[MIN]], [[MAX]].\ \ }
     Minimum and maximum.  The result value is the minimum or maximum,
     respectively, of the two source operands.

\item{[[ABS]].\ \ }
     Absolute value.  Compute the absolute value of the source operand.

\item{[[ROT]].\ \ }
     Rotate the value in the first source operand left or right by the amount
     specified in the second operand.  If the shift
     amount is positive, the value is rotated to the left (toward the
     most-significant bit); if it is negative, the value is rotated to
     the right.

\item{[[SEQ]], [[SNE]], [[SL]], [[SLE]].\ \ }
     Comparison instructions.  If the first source operand is equal, not
     equal, less than, or less than or equal, respectively, to the second
     operand, assign the integer value one to the destination operand.
     Otherwise, set the destination operand to zero.  The source operands
     must be either the same integer or floating point type, or two
     (possibly different) pointer types.

\item{[[JMP]].\ \ }
     Unconditional jump to the [[target]] label.

\item{[[JMPI]].\ \ }  Jump indirect. An unconditional jump to the
     computed address given in the source operand.  The [[target]]
     field is null.

\item{[[BTRUE]].\ \ }
     Branch if true.  If the source operand contains a true (non-zero)
     value, control is transferred to the code at the
     [[target]] label.  Otherwise, it continues with the next
     instruction in sequential order.  The source operand must have an
     integer type.

\item{[[BFALSE]].\ \ }
     Branch if false.  If the source operand contains a false (zero)
     value, control is transferred to the code at the
     [[target]] label.  Otherwise, it continues with the next instruction
     in sequential order.  The source operand must have an
     integer type.

\item{[[BEQ]],[[BNE]],[[BGE]],[[BGT]],[[BLE]],[[BLT]].\ \ } 
     Branch if conditional compare true.  The two source operands are
     compared according to the indicated condition.  If the result is
     true, control is transferred to the code at the
     [[target]] label.  Otherwise, it continues with the next
     instruction in sequential order.  The source operands must either have
     the same integer or floating-point type, or else two (possibly
     different) pointer types.

\item{[[MBR]].\ \ }
      Multi-way branch instruction.  Transfers control to one of several
      target labels depending on the value of the source operand,
      an integer.  The value of the source operand is compared with a
      set of constants to choose the target label.  If it matches one of
      these case constants, the instruction branches to the
      corresponding label. Otherwise, it branches to the default target
      label, which is the [[target]] field of the instruction.

      The case constants and target labels are stored in an
      [[instr_mbr_targets]] annotation of type [[MbrNote]].  (See the
      \emph{Machine-SUIF Machine Library} document.)  The case constants
      are guaranteed to be an increasing, non-empty sequence of integers.

\item{[[CALL]].\ \ } Call instruction.  The called procedure is either
      specified in a non-null [[target]] field or through a non-null first
      source operand whose value is the address of the callee.  (But not
      both: either the target symbol or the first source must be null.)
      The remaining source operands express the arguments.  The destination
      operand gives the result location for a value-returning call;
      otherwise, it is null.

\item{[[RET]].\ \ }
     Return from a procedure.  Only the first source operand is used and it
     is optional.  If specified, it is the return value and may contain
     an operand of any type except array or function types.  If the
     procedure's function type has void return type, the operand must be
     null; otherwise the operand must not be null and must have the same
     type as the return type of the procedure.


\item{[[ANY]].\ \ }
     Generic instruction, with arbitrary sources and destinations.  It is expected
     that one or more annotations will specify the exact operation and possibly
     its semantics.

\item{[[MRK]].\ \ }
     A pseudo-instruction marking a position in the program.  Used to
     hold miscellaneous annotations such as line numbers.

\end{itemize}


\section{Opcode functions and data structures}
\label{sec-opcodes}

This section defines the OPI functions and data structures associated
with the SUIFvm opcodes.  

\subsection{Target-specific data structures}

We start with the extensible opcode enumeration.

<<SUIFvm opcodes>>=
namespace suifvm {
enum {			// SUIFvm opcodes
    NOP = 2,
    CVT, LDA, LDC,
    ADD, SUB, NEG,
    MUL, DIV, REM, MOD,
    ABS, MIN, MAX,
    NOT, AND, IOR, XOR,
    ASR, LSL, LSR, ROT,
    MOV, LOD, STR, MEMCPY,
    SEQ, SNE, SL, SLE,
    BTRUE, BFALSE,
    BEQ, BNE, BGE, BGT, BLE, BLT,
    JMP, JMPI, MBR, CAL, RET,
    ANY, MRK
};
} // namespace suifvm

#define LAST_SUIFVM_OPCODE suifvm::MRK
@

The [[suifvm_opcode_names]] table is the extensible map from
a SUIFvm opcode to its name.  The [[suifvm_cnames]] table is the
extensible map from a SUIFvm opcode to a C-language
operator.  You can use the methods of the [[Vector]] template class
along with a redefinition of [[LAST_SUIFVM_OPCODE]] to extend the
SUIFvm instruction space.

<<SUIFvm opcode vectors>>=
extern Vector<char*> suifvm_opcode_names;
extern Vector<char*> suifvm_cnames;
@

We initialize these vectors using the following functions, invoked
in this library's initialization routine.

<<SUIFvm opcode vectors>>=
void init_suifvm_opcode_names();
void init_suifvm_cnames();
@


\subsection{OPI opcode functions}

We provide the typical set of opcode functions.

<<SUIFvm opcode OPI functions>>=
bool target_implements_suifvm(int opc);
char *opcode_name_suifvm(int opc);

int opcode_line_suifvm();
int opcode_ubr_suifvm();
int opcode_move_suifvm(TypeId);
int opcode_load_suifvm(TypeId);
int opcode_store_suifvm(TypeId);

int opcode_cbr_inverse_suifvm(int opc);
@


\subsection{Header file for [[opcodes.h]]}

<<opcodes.h>>=
/* file "suifvm/opcodes.h" */

<<Machine-SUIF copyright>>

#ifndef SUIFVM_OPCODES_H
#define SUIFVM_OPCODES_H

#include <machine/copyright.h>

#ifndef SUPPRESS_PRAGMA_INTERFACE
#pragma interface "suifvm/opcodes.h"
#endif

#include <machine/machine.h>

<<SUIFvm opcodes>>

<<SUIFvm opcode vectors>>

<<SUIFvm opcode OPI functions>>

#endif /* SUIFVM_OPCODES_H */
@
