\section{The SUIFvm target-characterization context}

This section begins with the declaration of the new interface context
[[SuifVmContext]].  Any target library that supports code generation
from SUIFvm needs to include a specialization of this context class
in its context class declaration.

The other context class defined in this section is a refinement of the
[[MachineContext]] class for use of [[suifvm]] as a target machine.


\subsection{Class [[SuifVmContext]]}

The [[SuifVmContext]] class has only a single method.  It allows us
to get access to the target code generator object.

<<class [[SuifVmContext]]>>=
class SuifVmContext {
  public:
    SuifVmContext();
    virtual ~SuifVmContext();

    virtual CodeGen* target_code_gen() const = 0;

  protected:
    <<[[SuifVmContext]] protected matter>>
};
@

<<[[SuifVmContext]] protected matter>>=
    mutable CodeGen *cached_code_gen;
@


\subsection{Class [[MachineContextSuifVm]]}

As a target, SUIFvm defines implementations for only the OPI functions
defined in the Machine-SUIF [[machine]] library.

<<class [[MachineContextSuifVm]]>>=
class MachineContextSuifVm
      : public virtual Context, public virtual MachineContext {
  public:
    MachineContextSuifVm() { }
    virtual ~MachineContextSuifVm() { }

    <<[[MachineContextSuifVm]] generic-pointer method>>

    <<[[MachineContextSuifVm]] printer methods>>

    <<[[MachineContextSuifVm]] code-finalizer method>>

    <<[[MachineContextSuifVm]] instruction-predicate methods>>

    <<[[MachineContextSuifVm]] opcode-generator methods>>

    <<[[MachineContextSuifVm]] opcode query methods>>

    <<[[MachineContextSuifVm]] register query method>>
};
@

The target's generic-pointer type, which corresponds to [[type_addr]]
in the [[machine]] library, is fetched by:

<<[[MachineContextSuifVm]] generic-pointer method>>=
    TypeId type_addr() const;
@

The target's [[Printer]] pointer, which corresponds to global variable
[[target_printer]] in the [[machine]] library, is fetched by:

<<[[MachineContextSuifVm]] printer methods>>=
    Printer* target_printer() const;
@

Similarly for the [[CPrinter]] pointer, which corresponds to global
variable [[target_c_printer]] in the [[machine]] library:

<<[[MachineContextSuifVm]] printer methods>>=
    CPrinter* target_c_printer() const;
@

The target's [[CodeFin]] generator, which corresponds to global function
[[target_code_fin]], should never be called, because code finalization is
not meaningful for the SUIFvm target.

<<[[MachineContextSuifVm]] code-finalizer method>>=
    CodeFin* target_code_fin() const { claim(false); return NULL; }
@

The target-specific instruction predicates can be used through
like-named methods of the [[Context]] class.

<<[[MachineContextSuifVm]] instruction-predicate methods>>=
    bool is_ldc(Instr*) const;
    bool is_move(Instr*) const;
    bool is_cmove(Instr*) const;
    bool is_line(Instr*) const;
    bool is_ubr(Instr*) const;
    bool is_cbr(Instr*) const;
    bool is_call(Instr*) const;
    bool is_return(Instr*) const;
    bool is_binary_exp(Instr*) const;
    bool is_unary_exp(Instr*) const;
    bool is_commutative(Instr*) const;
    bool is_two_opnd(Instr*) const;
    bool reads_memory(Instr*) const;
    bool writes_memory(Instr*) const;
    bool is_builtin(Instr*) const;
@

The target-specific opcode generators can be used via like-named methods of
the [[Context]] class.

<<[[MachineContextSuifVm]] opcode-generator methods>>=
    int opcode_line() const;
    int opcode_ubr() const;
    int opcode_move(TypeId) const;
    int opcode_load(TypeId) const;
    int opcode_store(TypeId) const;
    int opcode_cbr_inverse(int cbr_opcode) const;
@

The functions asking target-specific questions about opcodes can be used
via like-named [[Context]] methods.

<<[[MachineContextSuifVm]] opcode query methods>>=
    bool target_implements(int opcode) const;
    char* opcode_name(int opcode) const;
@

SUIFvm has no architectural registers, so we implement selected
[[reg_...]] methods of class [[MachineContext]] to give null results.

<<[[MachineContextSuifVm]] register query method>>=
    const Vector<const char*>& reg_names() const
	{ static Vector<const char*> empty; return empty; }
    const Vector<int>& reg_widths() const
	{ static Vector<int> empty; return empty; }
    const Vector<RegCells>& reg_models() const
	{ static Vector<RegCells> empty; return empty; }
    const NatSet* reg_allocatables(bool maximals = false) const
	{ static NatSetSparse empty; return &empty; }
    const NatSet* reg_caller_saves(bool maximals = false) const
	{ static NatSetSparse empty; return &empty; }
    const NatSet* reg_callee_saves(bool maximals = false) const
	{ static NatSetSparse empty; return &empty; }
@


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

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

<<Machine-SUIF copyright>>

#ifndef SUIFVM_CONTEXT_H
#define SUIFVM_CONTEXT_H

#include <machine/copyright.h>

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

#include <machine/machine.h>
#include <suifvm/suifvm.h>

<<class [[SuifVmContext]]>>

<<class [[MachineContextSuifVm]]>>

#endif /* SUIFVM_CONTEXT_H */
@
