\section{Support for code generation}
\label{sec-codegen}

This section describes a class called [[CodeGen]] that supports translation
of SUIFvm instructions to target-specific code.  A target-specific instance
of [[CodeGen]] is used by our [[gen]] pass to control its dispatch to
code-generation methods for each kind of SUIFvm instruction.

An OPI user gets access to a target-specific [[CodeGen]] object
by using the following OPI function.

<<function [[target_code_gen]]>>=
CodeGen* target_code_gen();
@

This is a target-specific function whose implementation is obtained
from the like-named method of the class [[SuifVmContext]], described
in the next section.


\subsection{Class [[CodeGen]]}

We present three views of the [[CodeGen]] class.  Those readers
interested in the OPI methods for code generation to an existing
target should read only the first subsection.  The second subsection
contains information relevant to those readers interested in defining
a [[CodeGen]] object for a new target.  The last subsection describes
details of our implementation.


\subsubsection{OPI details}

The following class defines a [[CodeGen]] object:

<<class [[CodeGen]]>>=
class CodeGen {
  public:
    virtual ~CodeGen() { }
    virtual void init(OptUnit *unit);	// must be called 1st!
    virtual void massage_unit(OptUnit *unit) { }
    virtual void finish(OptUnit *unit);	// must be called last!

    void translate_instr(OptUnit *unit, Instr*, InstrList *receiver);
    void translate_list(OptUnit *unit, InstrList *in_place);

    void emit(Instr*);

<<[[CodeGen]] private parts>>

<<[[CodeGen]] protected parts>>
};
@

Code generation is always done with respect to some
[[OptUnit]].  When your optimization pass starts working on
a new [[OptUnit]], you must call [[init]] to initialize the
code generator for this [[OptUnit]].  When your
optimization pass is done with an [[OptUnit]] where you did
some code generation, you must call [[finish]].  Under the current
implementation, you must call [[finish]] if you called [[init]], even if
you did not call any other method of [[CodeGen]].

The [[massage_unit]] method exists as a hook to make the code
generation of an entire optimization unit easier.  This hook allows us
to massage the semantics of a SUIFvm optimization unit into something
closer to the semantics of an optimization unit on the target.  We used to use
this hook in the Digital Alpha code generator, for example, to change
the prototype of calls to functions that return structures.  This call
is not guaranteed to be idempotent, so please be careful how you use
it.

Between calls to [[init]] and [[finish]], you can translate SUIFvm
instructions into target instructions using the [[translate_instr]] or
[[translate_list]] methods, which translate a single SUIFvm
instruction or a list of SUIFvm instructions into one or more target
instructions.


\subsubsection{Developing a target instance}

You develop a [[CodeGen]] object for a specific target (or class of
targets) by creating a derived class of [[CodeGen]].  The
[[CodeGenAlpha]] class found in the [[alpha]] library is
an example of such a derived class.

The derived class needs to define several methods that translate
SUIFvm instructions to instructions of the target machine.  The rest
of this section describes this process in detail.  During this
discussion, we will make reference to the protected parts of the
[[CodeGen]] class.  The majority of the protected data members in the
base class exist here simply because they are common to all derived
classes of [[CodeGen]].

<<[[CodeGen]] protected parts>>=
  protected:
    virtual void translate_null(Instr*) = 0;
    virtual void translate_nop(Instr*) = 0;
    virtual void translate_cvt(Instr*) = 0;
    virtual void translate_lda(Instr*) = 0;
    virtual void translate_ldc(Instr*) = 0;
    virtual void translate_add(Instr*) = 0;
    virtual void translate_sub(Instr*) = 0;
    virtual void translate_neg(Instr*) = 0;
    virtual void translate_mul(Instr*) = 0;
    virtual void translate_div(Instr*) = 0;
    virtual void translate_rem(Instr*) = 0;
    virtual void translate_mod(Instr*) = 0;
    virtual void translate_abs(Instr*) = 0;
    virtual void translate_min(Instr*) = 0;
    virtual void translate_max(Instr*) = 0;
    virtual void translate_not(Instr*) = 0;
    virtual void translate_and(Instr*) = 0;
    virtual void translate_ior(Instr*) = 0;
    virtual void translate_xor(Instr*) = 0;
    virtual void translate_asr(Instr*) = 0;
    virtual void translate_lsl(Instr*) = 0;
    virtual void translate_lsr(Instr*) = 0;
    virtual void translate_rot(Instr*) = 0;
    virtual void translate_mov(Instr*) = 0;
    virtual void translate_lod(Instr*) = 0;
    virtual void translate_str(Instr*) = 0;
    virtual void translate_memcpy(Instr*) = 0;
    virtual void translate_seq(Instr*) = 0;
    virtual void translate_sne(Instr*) = 0;
    virtual void translate_sl(Instr*) = 0;
    virtual void translate_sle(Instr*) = 0;
    virtual void translate_btrue(Instr*) = 0;
    virtual void translate_bfalse(Instr*) = 0;
    virtual void translate_beq(Instr*) = 0;
    virtual void translate_bne(Instr*) = 0;
    virtual void translate_bge(Instr*) = 0;
    virtual void translate_bgt(Instr*) = 0;
    virtual void translate_ble(Instr*) = 0;
    virtual void translate_blt(Instr*) = 0;
    virtual void translate_jmp(Instr*) = 0;
    virtual void translate_jmpi(Instr*) = 0;
    virtual void translate_mbr(Instr*) = 0;
    virtual void translate_cal(Instr*) = 0;
    virtual void translate_ret(Instr*) = 0;
    virtual void translate_any(Instr*) = 0;
    virtual void translate_mrk(Instr*) = 0;

    InstrList *receiver;		// client-provided output list
    Note line_note;			// prevailing source-line annotation

    // convenient variables
    OptUnit *cur_unit;			// defined by init()
    const char *cur_unit_name;		// name of current procedure
    CProcedureType *cur_unit_type;	// type of current procedure

    // variables that direct CodeGen
    bool report_int_overflow, report_int_divideby0;

    // working variables from cur_unit's stack_frame_info annotation
    bool is_leaf;
    bool is_varargs;
    int max_arg_area;

    virtual void transfer_params(OptUnit*, bool is_varargs) = 0;
    
    CodeGen() { }
@

We start our discussion with the methods that are required to appear
in any derived class.  The derived class must define a constructor.
You may also find it useful to redefine the virtual [[init]],
[[massage_unit]], and [[finish]] methods.  In the case of [[init]] and
[[finish]], you should always have your implementation of these
methods include a call to the base class [[init]] or [[finish]]
method.  The base class methods contain operations that you still want
to perform, e.g. the base-class [[init]] method will set many of the
variables declared in [[<<[[CodeGen]] protected parts>>]].  For
example, the base class [[init]] method initializes the data members
dependent upon the current [[OptUnit]].

Each [[translate_]]\emph{opcode} method is a pure virtual method.  Each
target library derives a subclass of [[CodeGen]] that implements these
methods.  Each implementation maps a SUIFvm instruction to one or more
instructions in the target architecture.  A translation function takes
a single parameter: a pointer to an [[Instr]].  The instruction is
assumed to be the SUIFvm instruction that you want to translate.  The
translated instructions are placed in an [[InstrList]] called
[[receiver]].

This class contains one other pure virtual method, [[transfer_params]]
that the target library must define.  It is invoked at the entry of a
procedure to create a sequence of instructions that connects the call
linkage conventions with the parameter symbols.


\subsubsection{Implementation details}

The following defines the private portion of the [[CodeGen]] class:

<<[[CodeGen]] private parts>>=
  private:
    void translate_mi(Instr*);
@

The [[translate_mi]] routine simply does the work common among all
of the public [[translate_*]] methods.


\subsection{Header file for module [[CodeGen.h]]}

The interface file has the following layout:

<<code\_gen.h>>=
/* file "suifvm/code_gen.h" */

<<Machine-SUIF copyright>>

#ifndef SUIFVM_CODE_GEN_H
#define SUIFVM_CODE_GEN_H

#include <machine/copyright.h>

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

#include <machine/machine.h>

<<class [[CodeGen]]>>

<<function [[target_code_gen]]>>

#endif /* SUIFVM_CODE_GEN_H */
@
