// -*- mode:c++ -*-

//Copyright (c) 2003, 2004, 2005
//The Regents of The University of Michigan
//All Rights Reserved

//This code is part of the M5 simulator, developed by Nathan Binkert,
//Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions
//from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi,
//and Andrew Schultz.

//Permission is granted to use, copy, create derivative works and
//redistribute this software and such derivative works for any purpose,
//so long as the copyright notice above, this grant of permission, and
//the disclaimer below appear in all copies made; and so long as the
//name of The University of Michigan is not used in any advertising or
//publicity pertaining to the use or distribution of this software
//without specific, written prior authorization.

//THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
//UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT
//WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR
//IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
//MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF
//THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,
//INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
//DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION
//WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

////////////////////////////////////////////////////////////////////
//
// Alpha ISA description file.
//
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//

output header {{
#include <sstream>
#include <iostream>
#include <iomanip>

#include "cpu/static_inst.hh"
#include "mem/mem_req.hh"  // some constructors use MemReq flags
}};

output decoder {{
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh"  // for Jump::branchTarget()

#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
}};

output exec {{
#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif

#ifdef FULL_SYSTEM
#include "arch/alpha/pseudo_inst.hh"
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
}};

////////////////////////////////////////////////////////////////////
//
// Namespace statement.  Everything below this line will be in the
// AlphaISAInst namespace.
//


namespace AlphaISA;

////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
//

// Universal (format-independent) fields
def bitfield OPCODE	<31:26>;
def bitfield RA		<25:21>;
def bitfield RB		<20:16>;

// Memory format
def signed bitfield MEMDISP <15: 0>; // displacement
def        bitfield MEMFUNC <15: 0>; // function code (same field, unsigned)

// Memory-format jumps
def bitfield JMPFUNC	<15:14>; // function code (disp<15:14>)
def bitfield JMPHINT	<13: 0>; // tgt Icache idx hint (disp<13:0>)

// Branch format
def signed bitfield BRDISP <20: 0>; // displacement

// Integer operate format(s>;
def bitfield INTIMM	<20:13>; // integer immediate (literal)
def bitfield IMM	<12:12>; // immediate flag
def bitfield INTFUNC	<11: 5>; // function code
def bitfield RC		< 4: 0>; // dest reg

// Floating-point operate format
def bitfield FA		  <25:21>;
def bitfield FB		  <20:16>;
def bitfield FP_FULLFUNC  <15: 5>; // complete function code
    def bitfield FP_TRAPMODE  <15:13>; // trapping mode
    def bitfield FP_ROUNDMODE <12:11>; // rounding mode
    def bitfield FP_TYPEFUNC  <10: 5>; // type+func: handiest for decoding
        def bitfield FP_SRCTYPE   <10: 9>; // source reg type
        def bitfield FP_SHORTFUNC < 8: 5>; // short function code
        def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code
def bitfield FC		  < 4: 0>; // dest reg

// PALcode format
def bitfield PALFUNC	<25: 0>; // function code

// EV5 PAL instructions:
// HW_LD/HW_ST
def bitfield HW_LDST_PHYS  <15>; // address is physical
def bitfield HW_LDST_ALT   <14>; // use ALT_MODE IPR
def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc
def bitfield HW_LDST_QUAD  <12>; // size: 0=32b, 1=64b
def bitfield HW_LDST_VPTE  <11>; // HW_LD only: is PTE fetch
def bitfield HW_LDST_LOCK  <10>; // HW_LD only: is load locked
def bitfield HW_LDST_COND  <10>; // HW_ST only: is store conditional
def signed bitfield HW_LDST_DISP  <9:0>; // signed displacement

// HW_REI
def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk
def bitfield HW_REI_MBZ <13: 0>; // must be zero

// HW_MTPR/MW_MFPR
def bitfield HW_IPR_IDX <15:0>;	 // IPR index

// M5 instructions
def bitfield M5FUNC <7:0>;

def operand_types {{
    'sb' : ('signed int', 8),
    'ub' : ('unsigned int', 8),
    'sw' : ('signed int', 16),
    'uw' : ('unsigned int', 16),
    'sl' : ('signed int', 32),
    'ul' : ('unsigned int', 32),
    'sq' : ('signed int', 64),
    'uq' : ('unsigned int', 64),
    'sf' : ('float', 32),
    'df' : ('float', 64)
}};

def operands {{
    # Int regs default to unsigned, but code should not count on this.
    # For clarity, descriptions that depend on unsigned behavior should
    # explicitly specify '.uq'.
    'Ra': IntRegOperandTraits('uq', 'RA', 'IsInteger', 1),
    'Rb': IntRegOperandTraits('uq', 'RB', 'IsInteger', 2),
    'Rc': IntRegOperandTraits('uq', 'RC', 'IsInteger', 3),
    'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1),
    'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2),
    'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3),
    'Mem': MemOperandTraits('uq', None,
                            ('IsMemRef', 'IsLoad', 'IsStore'), 4),
    'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4),
    'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1),
    'FPCR':  ControlRegOperandTraits('uq', 'Fpcr', None, 1),
    # The next two are hacks for non-full-system call-pal emulation
    'R0':  IntRegOperandTraits('uq', '0', None, 1),
    'R16': IntRegOperandTraits('uq', '16', None, 1)
}};

////////////////////////////////////////////////////////////////////
//
// Basic instruction classes/templates/formats etc.
//

output header {{
// uncomment the following to get SimpleScalar-compatible disassembly
// (useful for diffing output traces).
// #define SS_COMPATIBLE_DISASSEMBLY

    /**
     * Base class for all Alpha static instructions.
     */
    class AlphaStaticInst : public StaticInst<AlphaISA>
    {
      protected:

	/// Make AlphaISA register dependence tags directly visible in
	/// this class and derived classes.  Maybe these should really
	/// live here and not in the AlphaISA namespace.
	enum DependenceTags {
	    FP_Base_DepTag = AlphaISA::FP_Base_DepTag,
	    Fpcr_DepTag = AlphaISA::Fpcr_DepTag,
	    Uniq_DepTag = AlphaISA::Uniq_DepTag,
	    IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag
	};

	/// Constructor.
	AlphaStaticInst(const char *mnem, MachInst _machInst,
			OpClass __opClass)
	    : StaticInst<AlphaISA>(mnem, _machInst, __opClass)
	{
	}

	/// Print a register name for disassembly given the unique
	/// dependence tag number (FP or int).
	void printReg(std::ostream &os, int reg) const;

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    void
    AlphaStaticInst::printReg(std::ostream &os, int reg) const
    {
	if (reg < FP_Base_DepTag) {
	    ccprintf(os, "r%d", reg);
	}
	else {
	    ccprintf(os, "f%d", reg - FP_Base_DepTag);
	}
    }

    std::string
    AlphaStaticInst::generateDisassembly(Addr pc,
					 const SymbolTable *symtab) const
    {
	std::stringstream ss;

	ccprintf(ss, "%-10s ", mnemonic);

	// just print the first two source regs... if there's
	// a third one, it's a read-modify-write dest (Rc),
	// e.g. for CMOVxx
	if (_numSrcRegs > 0) {
	    printReg(ss, _srcRegIdx[0]);
	}
	if (_numSrcRegs > 1) {
	    ss << ",";
	    printReg(ss, _srcRegIdx[1]);
	}

	// just print the first dest... if there's a second one,
	// it's generally implicit
	if (_numDestRegs > 0) {
	    if (_numSrcRegs > 0)
		ss << ",";
	    printReg(ss, _destRegIdx[0]);
	}

	return ss.str();
    }
}};

// Declarations for execute() methods.
def template BasicExecDeclare {{
    Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};

// Basic instruction class declaration template.
def template BasicDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      public:
	/// Constructor.
	%(class_name)s(MachInst machInst);

	%(BasicExecDeclare)s
    };
}};

// Basic instruction class constructor template.
def template BasicConstructor {{
    inline %(class_name)s::%(class_name)s(MachInst machInst)
	 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
    {
	%(constructor)s;
    }
}};

// Basic instruction class execute method template.
def template BasicExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
				  Trace::InstRecord *traceData) const
    {
	Fault fault = No_Fault;

	%(fp_enable_check)s;
	%(op_decl)s;
	%(op_rd)s;
	%(code)s;

	if (fault == No_Fault) {
	    %(op_wb)s;
	}

	return fault;
    }
}};

// Basic decode template.
def template BasicDecode {{
    return new %(class_name)s(machInst);
}};

// Basic decode template, passing mnemonic in as string arg to constructor.
def template BasicDecodeWithMnemonic {{
    return new %(class_name)s("%(mnemonic)s", machInst);
}};

// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
    iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), flags)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};



////////////////////////////////////////////////////////////////////
//
// Nop
//

output header {{
    /**
     * Static instruction class for no-ops.  This is a leaf class.
     */
    class Nop : public AlphaStaticInst
    {
	/// Disassembly of original instruction.
	const std::string originalDisassembly;

      public:
	/// Constructor
	Nop(const std::string _originalDisassembly, MachInst _machInst)
	    : AlphaStaticInst("nop", _machInst, No_OpClass),
	      originalDisassembly(_originalDisassembly)
	{
	    flags[IsNop] = true;
	}

	~Nop() { }

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;

	%(BasicExecDeclare)s
    };
}};

output decoder {{
    std::string Nop::generateDisassembly(Addr pc,
					 const SymbolTable *symtab) const
    {
#ifdef SS_COMPATIBLE_DISASSEMBLY
	return originalDisassembly;
#else
	return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
    }

    /// Helper function for decoding nops.  Substitute Nop object
    /// for original inst passed in as arg (and delete latter).
    inline
    AlphaStaticInst *
    makeNop(AlphaStaticInst *inst)
    {
	AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
	delete inst;
	return nop;
    }
}};

output exec {{
    Fault
    Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
    {
	return No_Fault;
    }
}};

// integer & FP operate instructions use Rc as dest, so check for
// Rc == 31 to detect nops
def template OperateNopCheckDecode {{
 {
     AlphaStaticInst *i = new %(class_name)s(machInst);
     if (RC == 31) {
         i = makeNop(i);
     }
     return i;
 }
}};

// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
    iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
			opt_args)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = OperateNopCheckDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};


////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//

output header {{
    /**
     * Base class for integer immediate instructions.
     */
    class IntegerImm : public AlphaStaticInst
    {
      protected:
	/// Immediate operand value (unsigned 8-bit int).
	uint8_t imm;

	/// Constructor
	IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass)
	    : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM)
	{
	}

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    std::string
    IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	std::stringstream ss;

	ccprintf(ss, "%-10s ", mnemonic);

	// just print the first source reg... if there's
	// a second one, it's a read-modify-write dest (Rc),
	// e.g. for CMOVxx
	if (_numSrcRegs > 0) {
	    printReg(ss, _srcRegIdx[0]);
	    ss << ",";
	}

	ss << (int)imm;
 
	if (_numDestRegs > 0) {
	    ss << ",";
	    printReg(ss, _destRegIdx[0]);
	}

	return ss.str();
    }
}};


def template RegOrImmDecode {{
 {
     AlphaStaticInst *i =
         (IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst)
               : (AlphaStaticInst *)new %(class_name)s(machInst);
     if (RC == 31) {
         i = makeNop(i);
     }
     return i;
 }
}};

// Primary format for integer operate instructions:
// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used.
// - Generates NOP if RC == 31.
def format IntegerOperate(code, *opt_flags) {{
    # If the code block contains 'Rb_or_imm', we define two instructions,
    # one using 'Rb' and one using 'imm', and have the decoder select
    # the right one.
    uses_imm = (code.find('Rb_or_imm') != -1)
    if uses_imm:
	orig_code = code
        # base code is reg version:
        # rewrite by substituting 'Rb' for 'Rb_or_imm'
	code = re.sub(r'Rb_or_imm', 'Rb', orig_code)
        # generate immediate version by substituting 'imm'
        # note that imm takes no extenstion, so we extend
        # the regexp to replace any extension as well
        imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code)

    # generate declaration for register version
    cblk = CodeBlock(code)
    iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    exec_output = BasicExecute.subst(iop)

    if uses_imm:
        # append declaration for imm version
        imm_cblk = CodeBlock(imm_code)
        imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk,
				opt_flags)
	header_output += BasicDeclare.subst(imm_iop)
        decoder_output += BasicConstructor.subst(imm_iop)
        exec_output += BasicExecute.subst(imm_iop)
        # decode checks IMM bit to pick correct version
	decode_block = RegOrImmDecode.subst(iop)
    else:
        # no imm version: just check for nop
        decode_block = OperateNopCheckDecode.subst(iop)
}};


////////////////////////////////////////////////////////////////////
//
// Floating-point instructions
//
//	Note that many FP-type instructions which do not support all the
//	various rounding & trapping modes use the simpler format
//	BasicOperateWithNopCheck.
//

output exec {{
    /// Check "FP enabled" machine status bit.  Called when executing any FP
    /// instruction in full-system mode.
    /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault
    /// if not.  Non-full-system mode: always returns No_Fault.
#ifdef FULL_SYSTEM
    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
    {
	Fault fault = No_Fault;	// dummy... this ipr access should not fault
	if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) {
	    fault = Fen_Fault;
	}
	return fault;
    }
#else
    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
    {
	return No_Fault;
    }
#endif
}};

output header {{
    /**
     * Base class for general floating-point instructions.  Includes
     * support for various Alpha rounding and trapping modes.  Only FP
     * instructions that require this support are derived from this
     * class; the rest derive directly from AlphaStaticInst.
     */
    class AlphaFP : public  AlphaStaticInst
    {
      public:
	/// Alpha FP rounding modes.
	enum RoundingMode {
	    Chopped = 0,	///< round toward zero
	    Minus_Infinity = 1, ///< round toward minus infinity
	    Normal = 2,		///< round to nearest (default)
	    Dynamic = 3,	///< use FPCR setting (in instruction)
	    Plus_Infinity = 3	///< round to plus inifinity (in FPCR)
	};

	/// Alpha FP trapping modes.
	/// For instructions that produce integer results, the
	/// "Underflow Enable" modes really mean "Overflow Enable", and
	/// the assembly modifier is V rather than U.
	enum TrappingMode {
	    /// default: nothing enabled
	    Imprecise = 0,		   ///< no modifier
	    /// underflow/overflow traps enabled, inexact disabled
	    Underflow_Imprecise = 1,	   ///< /U or /V
	    Underflow_Precise = 5,	   ///< /SU or /SV
	    /// underflow/overflow and inexact traps enabled
	    Underflow_Inexact_Precise = 7  ///< /SUI or /SVI
	};

      protected:
#if defined(linux)
	static const int alphaToC99RoundingMode[];
#endif

	/// Map enum RoundingMode values to disassembly suffixes.
	static const char *roundingModeSuffix[];
	/// Map enum TrappingMode values to FP disassembly suffixes.
	static const char *fpTrappingModeSuffix[];
	/// Map enum TrappingMode values to integer disassembly suffixes.
	static const char *intTrappingModeSuffix[];

	/// This instruction's rounding mode.
	RoundingMode roundingMode;
	/// This instruction's trapping mode.
	TrappingMode trappingMode;

	/// Constructor
	AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass)
	    : AlphaStaticInst(mnem, _machInst, __opClass),
	      roundingMode((enum RoundingMode)FP_ROUNDMODE),
	      trappingMode((enum TrappingMode)FP_TRAPMODE)
	{
	    if (trappingMode != Imprecise) {
		warn("precise FP traps unimplemented\n");
	    }
	}

#if defined(linux)
	int getC99RoundingMode(uint64_t fpcr_val) const;
#endif

	// This differs from the AlphaStaticInst version only in
	// printing suffixes for non-default rounding & trapping modes.
	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };

}};


def template FloatingPointDecode {{
 {
     bool fast = (FP_TRAPMODE == AlphaFP::Imprecise
		  && FP_ROUNDMODE == AlphaFP::Normal);
     AlphaStaticInst *i =
	 fast ? (AlphaStaticInst *)new %(class_name)sFast(machInst) :
	        (AlphaStaticInst *)new %(class_name)sGeneral(machInst);

     if (FC == 31) {
	 i = makeNop(i);
     }

     return i;
 }
}};

output decoder {{
#if defined(linux)
    int
    AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
    {
	if (roundingMode == Dynamic) {
	    return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
	}
	else {
	    return alphaToC99RoundingMode[roundingMode];
	}
    }
#endif

    std::string
    AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	std::string mnem_str(mnemonic);

#ifndef SS_COMPATIBLE_DISASSEMBLY
	std::string suffix("");
	suffix += ((_destRegIdx[0] >= FP_Base_DepTag)
		   ? fpTrappingModeSuffix[trappingMode]
		   : intTrappingModeSuffix[trappingMode]);
	suffix += roundingModeSuffix[roundingMode];

	if (suffix != "") {
	    mnem_str = csprintf("%s/%s", mnemonic, suffix);
	}
#endif

	std::stringstream ss;
	ccprintf(ss, "%-10s ", mnem_str.c_str());

	// just print the first two source regs... if there's
	// a third one, it's a read-modify-write dest (Rc),
	// e.g. for CMOVxx
	if (_numSrcRegs > 0) {
	    printReg(ss, _srcRegIdx[0]);
	}
	if (_numSrcRegs > 1) {
	    ss << ",";
	    printReg(ss, _srcRegIdx[1]);
	}

	// just print the first dest... if there's a second one,
	// it's generally implicit
	if (_numDestRegs > 0) {
	    if (_numSrcRegs > 0)
		ss << ",";
	    printReg(ss, _destRegIdx[0]);
	}

	return ss.str();
    }

#if defined(linux)
    const int AlphaFP::alphaToC99RoundingMode[] = {
	FE_TOWARDZERO,	// Chopped
	FE_DOWNWARD,	// Minus_Infinity
	FE_TONEAREST,	// Normal
	FE_UPWARD	// Dynamic in inst, Plus_Infinity in FPCR
    };
#endif

    const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
    // mark invalid trapping modes, but don't fail on them, because
    // you could decode anything on a misspeculated path
    const char *AlphaFP::fpTrappingModeSuffix[] =
	{ "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
    const char *AlphaFP::intTrappingModeSuffix[] =
	{ "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
}};

// General format for floating-point operate instructions:
// - Checks trapping and rounding mode flags.  Trapping modes
//   currently unimplemented (will fail).
// - Generates NOP if FC == 31.
def format FloatingPointOperate(code, *opt_args) {{
    iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args)
    decode_block = FloatingPointDecode.subst(iop)

    fast_iop = InstObjParams(name, Name + 'Fast', 'AlphaFP',
			     CodeBlock(code), opt_args)
    header_output = BasicDeclare.subst(fast_iop)
    decoder_output = BasicConstructor.subst(fast_iop)
    exec_output = BasicExecute.subst(fast_iop)

    gen_code_prefix = r'''
#if defined(linux)
    fesetround(getC99RoundingMode(xc->readFpcr()));
#endif
'''
    gen_code_suffix = r'''
#if defined(linux)
    fesetround(FE_TONEAREST);
#endif
'''

    gen_iop = InstObjParams(name, Name + 'General', 'AlphaFP',
    CodeBlock(gen_code_prefix + code + gen_code_suffix), opt_args)
    header_output += BasicDeclare.subst(gen_iop)
    decoder_output += BasicConstructor.subst(gen_iop)
    exec_output += BasicExecute.subst(gen_iop)
}};


////////////////////////////////////////////////////////////////////
//
// Memory-format instructions: LoadAddress, Load, Store
//

output header {{
    /**
     * Base class for general Alpha memory-format instructions.
     */
    class Memory : public AlphaStaticInst
    {
      protected:

	/// Memory request flags.  See mem_req_base.hh.
        unsigned memAccessFlags;
	/// Pointer to EAComp object.
	const StaticInstPtr<AlphaISA> eaCompPtr;
	/// Pointer to MemAcc object.
	const StaticInstPtr<AlphaISA> memAccPtr;

	/// Constructor
	Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
	       StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
	       StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
	    : AlphaStaticInst(mnem, _machInst, __opClass),
	      memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
	{
	}

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;

      public:

	const StaticInstPtr<AlphaISA> &eaCompInst() const { return eaCompPtr; }
	const StaticInstPtr<AlphaISA> &memAccInst() const { return memAccPtr; }
    };

    /**
     * Base class for memory-format instructions using a 32-bit
     * displacement (i.e. most of them).
     */
    class MemoryDisp32 : public Memory
    {
      protected:
	/// Displacement for EA calculation (signed).
	int32_t disp;

	/// Constructor.
	MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass,
		     StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
		     StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
	    : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
	      disp(MEMDISP)
	{
	}
    };


    /**
     * Base class for a few miscellaneous memory-format insts
     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
     * None of these instructions has a destination register either.
     */
    class MemoryNoDisp : public Memory
    {
      protected:
	/// Constructor
	MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass,
		     StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
		     StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
	    : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
	{
	}

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};


output decoder {{
    std::string
    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
			flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
    }

    std::string
    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	return csprintf("%-10s (r%d)", mnemonic, RB);
    }
}};

def format LoadAddress(code) {{
    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};


def template LoadStoreDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      protected:

	/**
	 * "Fake" effective address computation class for "%(mnemonic)s".
	 */
	class EAComp : public %(base_class)s
	{
	  public:
	    /// Constructor
	    EAComp(MachInst machInst);

            %(BasicExecDeclare)s
	};

	/**
	 * "Fake" memory access instruction class for "%(mnemonic)s".
	 */
	class MemAcc : public %(base_class)s
	{
	  public:
	    /// Constructor
	    MemAcc(MachInst machInst);

            %(BasicExecDeclare)s
	};

      public:

	/// Constructor.
	%(class_name)s(MachInst machInst);

	%(BasicExecDeclare)s
    };
}};

def template LoadStoreConstructor {{
    /** TODO: change op_class to AddrGenOp or something (requires
     * creating new member of OpClass enum in op_class.hh, updating
     * config files, etc.). */
    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
	: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
    {
	%(ea_constructor)s;
    }

    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
	: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
    {
	%(memacc_constructor)s;
    }

    inline %(class_name)s::%(class_name)s(MachInst machInst)
	 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
			  new EAComp(machInst), new MemAcc(machInst))
    {
	%(constructor)s;
    }
}};


def template EACompExecute {{
    Fault
    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
				   Trace::InstRecord *traceData) const
    {
	Addr EA;
	Fault fault = No_Fault;

	%(fp_enable_check)s;
	%(op_decl)s;
	%(op_rd)s;
	%(code)s;

	if (fault == No_Fault) {
	    %(op_wb)s;
	    xc->setEA(EA);
	}

	return fault;
    }
}};

def template MemAccExecute {{
    Fault
    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
				   Trace::InstRecord *traceData) const
    {
	Addr EA;
	Fault fault = No_Fault;

	%(fp_enable_check)s;
	%(op_decl)s;
	%(op_nonmem_rd)s;
	EA = xc->getEA();
	
	if (fault == No_Fault) {
	    %(op_mem_rd)s;
	    %(code)s;
	}

	if (fault == No_Fault) {
	    %(op_mem_wb)s;
	}

	if (fault == No_Fault) {
	    %(postacc_code)s;
	}

	if (fault == No_Fault) {
	    %(op_nonmem_wb)s;
	}

	return fault;
    }
}};


def template LoadStoreExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
				  Trace::InstRecord *traceData) const
    {
	Addr EA;
	Fault fault = No_Fault;

	%(fp_enable_check)s;
	%(op_decl)s;
	%(op_nonmem_rd)s;
	%(ea_code)s;

	if (fault == No_Fault) {
	    %(op_mem_rd)s;
	    %(memacc_code)s;
	}

	if (fault == No_Fault) {
	    %(op_mem_wb)s;
	}

	if (fault == No_Fault) {
	    %(postacc_code)s;
	}

	if (fault == No_Fault) {
	    %(op_nonmem_wb)s;
	}

	return fault;
    }
}};


def template PrefetchExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
				  Trace::InstRecord *traceData) const
    {
	Addr EA;
	Fault fault = No_Fault;

	%(fp_enable_check)s;
	%(op_decl)s;
	%(op_nonmem_rd)s;
	%(ea_code)s;

	if (fault == No_Fault) {
	    xc->prefetch(EA, memAccessFlags);
	}

	return No_Fault;
    }
}};

// load instructions use Ra as dest, so check for
// Ra == 31 to detect nops
def template LoadNopCheckDecode {{
 {
     AlphaStaticInst *i = new %(class_name)s(machInst);
     if (RA == 31) {
	 i = makeNop(i);
     }
     return i;
 }
}};


// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
def template LoadPrefetchCheckDecode {{
 {
     if (RA != 31) {
	 return new %(class_name)s(machInst);
     }
     else {
	 return new %(class_name)sPrefetch(machInst);
     }
 }
}};


let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',
		  base_class = 'MemoryDisp32', flags = [],
		  decode_template = BasicDecode,
		  exec_template = LoadStoreExecute):
    # Segregate flags into instruction flags (handled by InstObjParams)
    # and memory access flags (handled here).

    # Would be nice to autogenerate this list, but oh well.
    valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE']
    mem_flags =  [f for f in flags if f in valid_mem_flags]
    inst_flags = [f for f in flags if f not in valid_mem_flags]

    # add hook to get effective addresses into execution trace output.
    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'

    # generate code block objects
    ea_cblk = CodeBlock(ea_code)
    memacc_cblk = CodeBlock(memacc_code)
    postacc_cblk = CodeBlock(postacc_code)

    # Some CPU models execute the memory operation as an atomic unit,
    # while others want to separate them into an effective address
    # computation and a memory access operation.  As a result, we need
    # to generate three StaticInst objects.  Note that the latter two
    # are nested inside the larger "atomic" one.

    # generate InstObjParams for EAComp object
    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
    
    # generate InstObjParams for MemAcc object
    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
    # in the split execution model, the MemAcc portion is responsible
    # for the post-access code.
    memacc_iop.postacc_code = postacc_cblk.code

    # generate InstObjParams for unified execution
    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)

    iop.ea_constructor = ea_cblk.constructor
    iop.ea_code = ea_cblk.code
    iop.memacc_constructor = memacc_cblk.constructor
    iop.memacc_code = memacc_cblk.code
    iop.postacc_code = postacc_cblk.code

    if mem_flags:
        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
        iop.constructor += s
        memacc_iop.constructor += s

    # (header_output, decoder_output, decode_block, exec_output)
    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
	    decode_template.subst(iop),
            EACompExecute.subst(ea_iop)
            + MemAccExecute.subst(memacc_iop)
            + exec_template.subst(iop))
}};


def format LoadOrNop(ea_code, memacc_code, *flags) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
                      decode_template = LoadNopCheckDecode)
}};


// Note that the flags passed in apply only to the prefetch version
def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{
    # declare the load instruction object and generate the decode block
    (header_output, decoder_output, decode_block, exec_output) = \
	LoadStoreBase(name, Name, ea_code, memacc_code,
		      decode_template = LoadPrefetchCheckDecode)

    # Declare the prefetch instruction object.

    # convert flags from tuple to list to make them mutable
    pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT']

    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
	LoadStoreBase(name, Name + 'Prefetch', ea_code, '',
		      flags = pf_flags, exec_template = PrefetchExecute)

    header_output += pf_header_output
    decoder_output += pf_decoder_output
    exec_output += pf_exec_output
}};


def format Store(ea_code, memacc_code, *flags) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags)
}};


def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code,
                      flags = flags)
}};


// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
def format MiscPrefetch(ea_code, memacc_code, *flags) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
                      base_class = 'MemoryNoDisp')
}};


////////////////////////////////////////////////////////////////////
//
// Control transfer instructions
//

output header {{

    /**
     * Base class for instructions whose disassembly is not purely a
     * function of the machine instruction (i.e., it depends on the
     * PC).  This class overrides the disassemble() method to check
     * the PC and symbol table values before re-using a cached
     * disassembly string.  This is necessary for branches and jumps,
     * where the disassembly string includes the target address (which
     * may depend on the PC and/or symbol table).
     */
    class PCDependentDisassembly : public AlphaStaticInst
    {
      protected:
	/// Cached program counter from last disassembly
	mutable Addr cachedPC;
	/// Cached symbol table pointer from last disassembly
	mutable const SymbolTable *cachedSymtab;

	/// Constructor
	PCDependentDisassembly(const char *mnem, MachInst _machInst,
			       OpClass __opClass)
	    : AlphaStaticInst(mnem, _machInst, __opClass),
	      cachedPC(0), cachedSymtab(0)
	{
	}

	const std::string &
	disassemble(Addr pc, const SymbolTable *symtab) const;
    };

    /**
     * Base class for branches (PC-relative control transfers),
     * conditional or unconditional.
     */
    class Branch : public PCDependentDisassembly
    {
      protected:
	/// Displacement to target address (signed).
	int32_t disp;

	/// Constructor.
	Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
	    : PCDependentDisassembly(mnem, _machInst, __opClass),
	      disp(BRDISP << 2)
	{
	}

	Addr branchTarget(Addr branchPC) const;

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };

    /**
     * Base class for jumps (register-indirect control transfers).  In
     * the Alpha ISA, these are always unconditional.
     */
    class Jump : public PCDependentDisassembly
    {
      protected:

	/// Displacement to target address (signed).
	int32_t disp;

      public:
	/// Constructor
	Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
	    : PCDependentDisassembly(mnem, _machInst, __opClass),
	      disp(BRDISP)
	{
	}

	Addr branchTarget(ExecContext *xc) const;

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    Addr
    Branch::branchTarget(Addr branchPC) const
    {
	return branchPC + 4 + disp;
    }

    Addr
    Jump::branchTarget(ExecContext *xc) const
    {
	Addr NPC = xc->readPC() + 4;
	uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
	return (Rb & ~3) | (NPC & 1);
    }

    const std::string &
    PCDependentDisassembly::disassemble(Addr pc,
					const SymbolTable *symtab) const
    {
	if (!cachedDisassembly ||
	    pc != cachedPC || symtab != cachedSymtab)
	{
	    if (cachedDisassembly)
		delete cachedDisassembly;

	    cachedDisassembly =
		new std::string(generateDisassembly(pc, symtab));
	    cachedPC = pc;
	    cachedSymtab = symtab;
	}

	return *cachedDisassembly;
    }

    std::string
    Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	std::stringstream ss;

	ccprintf(ss, "%-10s ", mnemonic);

	// There's only one register arg (RA), but it could be
	// either a source (the condition for conditional
	// branches) or a destination (the link reg for
	// unconditional branches)
	if (_numSrcRegs > 0) {
	    printReg(ss, _srcRegIdx[0]);
	    ss << ",";
	}
	else if (_numDestRegs > 0) {
	    printReg(ss, _destRegIdx[0]);
	    ss << ",";
	}

#ifdef SS_COMPATIBLE_DISASSEMBLY
	if (_numSrcRegs == 0 && _numDestRegs == 0) {
	    printReg(ss, 31);
	    ss << ",";
	}
#endif

	Addr target = pc + 4 + disp;

	std::string str;
	if (symtab && symtab->findSymbol(target, str))
	    ss << str;
	else 
	    ccprintf(ss, "0x%x", target);

	return ss.str();
    }

    std::string
    Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	std::stringstream ss;

	ccprintf(ss, "%-10s ", mnemonic);

#ifdef SS_COMPATIBLE_DISASSEMBLY
	if (_numDestRegs == 0) {
	    printReg(ss, 31);
	    ss << ",";
	}
#endif

	if (_numDestRegs > 0) {
	    printReg(ss, _destRegIdx[0]);
	    ss << ",";
	}

	ccprintf(ss, "(r%d)", RB);

	return ss.str();
    }
}};

def template JumpOrBranchDecode {{
    return (RA == 31)
	? (StaticInst<AlphaISA> *)new %(class_name)s(machInst)
	: (StaticInst<AlphaISA> *)new %(class_name)sAndLink(machInst);
}};

def format CondBranch(code) {{
    code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
    iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
			('IsDirectControl', 'IsCondControl'))
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

let {{
def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
    # Declare basic control transfer w/o link (i.e. link reg is R31)
    nolink_code = 'NPC = %s;\n' % npc_expr
    nolink_iop = InstObjParams(name, Name, base_class,
                               CodeBlock(nolink_code), flags)
    header_output = BasicDeclare.subst(nolink_iop)
    decoder_output = BasicConstructor.subst(nolink_iop)
    exec_output = BasicExecute.subst(nolink_iop)

    # Generate declaration of '*AndLink' version, append to decls
    link_code = 'Ra = NPC & ~3;\n' + nolink_code
    link_iop = InstObjParams(name, Name + 'AndLink', base_class,
                             CodeBlock(link_code), flags)
    header_output += BasicDeclare.subst(link_iop)
    decoder_output += BasicConstructor.subst(link_iop)
    exec_output += BasicExecute.subst(link_iop)

    # need to use link_iop for the decode template since it is expecting
    # the shorter version of class_name (w/o "AndLink")

    return (header_output, decoder_output,
            JumpOrBranchDecode.subst(nolink_iop), exec_output)
}};

def format UncondBranch(*flags) {{
    flags += ('IsUncondControl', 'IsDirectControl')
    (header_output, decoder_output, decode_block, exec_output) = \
        UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags)
}};

def format Jump(*flags) {{
    flags += ('IsUncondControl', 'IsIndirectControl')
    (header_output, decoder_output, decode_block, exec_output) = \
        UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags)
}};


////////////////////////////////////////////////////////////////////
//
// PAL calls
//

output header {{
    /**
     * Base class for emulated call_pal calls (used only in
     * non-full-system mode).
     */
    class EmulatedCallPal : public AlphaStaticInst
    {
      protected:

	/// Constructor.
	EmulatedCallPal(const char *mnem, MachInst _machInst,
			OpClass __opClass)
	    : AlphaStaticInst(mnem, _machInst, __opClass)
	{
	}

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    std::string
    EmulatedCallPal::generateDisassembly(Addr pc,
					 const SymbolTable *symtab) const
    {
#ifdef SS_COMPATIBLE_DISASSEMBLY
	return csprintf("%s %s", "call_pal", mnemonic);
#else
	return csprintf("%-10s %s", "call_pal", mnemonic);
#endif
    }
}};

def format EmulatedCallPal(code, *flags) {{
    iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

output header {{
    /**
     * Base class for full-system-mode call_pal instructions.
     * Probably could turn this into a leaf class and get rid of the
     * parser template.
     */
    class CallPalBase : public AlphaStaticInst
    {
      protected:
	int palFunc;	///< Function code part of instruction
	int palOffset;	///< Target PC, offset from IPR_PAL_BASE
	bool palValid;	///< is the function code valid?
	bool palPriv;	///< is this call privileged?

	/// Constructor.
	CallPalBase(const char *mnem, MachInst _machInst,
		    OpClass __opClass);

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    inline
    CallPalBase::CallPalBase(const char *mnem, MachInst _machInst,
			     OpClass __opClass)
	: AlphaStaticInst(mnem, _machInst, __opClass),
	palFunc(PALFUNC)
    {
	// From the 21164 HRM (paraphrased):
	// Bit 7 of the function code (mask 0x80) indicates
	// whether the call is privileged (bit 7 == 0) or
	// unprivileged (bit 7 == 1).  The privileged call table
	// starts at 0x2000, the unprivielged call table starts at
	// 0x3000.  Bits 5-0 (mask 0x3f) are used to calculate the
	// offset.
	const int palPrivMask = 0x80;
	const int palOffsetMask = 0x3f;

	// Pal call is invalid unless all other bits are 0
	palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
	palPriv = ((machInst & palPrivMask) == 0);
	int shortPalFunc = (machInst & palOffsetMask);
	// Add 1 to base to set pal-mode bit
	palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
    }

    std::string
    CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	return csprintf("%-10s %#x", "call_pal", palFunc);
    }
}};

def format CallPal(code, *flags) {{
    iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

////////////////////////////////////////////////////////////////////
//
// hw_ld, hw_st
//

output header {{
    /**
     * Base class for hw_ld and hw_st.
     */
    class HwLoadStore : public Memory
    {
      protected:

	/// Displacement for EA calculation (signed).
	int16_t disp;

	/// Constructor
	HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass,
		    StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
		    StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr);

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};


output decoder {{
    inline
    HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst,
			     OpClass __opClass,
			     StaticInstPtr<AlphaISA> _eaCompPtr,
			     StaticInstPtr<AlphaISA> _memAccPtr)
	: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
	disp(HW_LDST_DISP)
    {
	memAccessFlags = 0;
	if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL;
	if (HW_LDST_ALT)  memAccessFlags |= ALTMODE;
	if (HW_LDST_VPTE) memAccessFlags |= VPTE;
	if (HW_LDST_LOCK) memAccessFlags |= LOCKED;
    }

    std::string
    HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
#ifdef SS_COMPATIBLE_DISASSEMBLY
	return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
#else
	// HW_LDST_LOCK and HW_LDST_COND are the same bit.
	const char *lock_str =
	    (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : "";

	return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s",
			mnemonic, RA, disp, RB,
			HW_LDST_PHYS ? ",PHYS" : "",
			HW_LDST_ALT ? ",ALT" : "",
			HW_LDST_QUAD ? ",QUAD" : "",
			HW_LDST_VPTE ? ",VPTE" : "",
			lock_str);
#endif
    }
}};

def format HwLoadStore(ea_code, memacc_code, class_ext, *flags) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
		      flags = flags, base_class = 'HwLoadStore')
}};


def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
		      postacc_code, flags = flags, base_class = 'HwLoadStore')
}};


output header {{
    /**
     * Base class for hw_mfpr and hw_mtpr.
     */
    class HwMoveIPR : public AlphaStaticInst
    {
      protected:
	/// Index of internal processor register.
	int ipr_index;

	/// Constructor
	HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass)
	    : AlphaStaticInst(mnem, _machInst, __opClass),
	      ipr_index(HW_IPR_IDX)
	{
	}

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    std::string
    HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	if (_numSrcRegs > 0) {
	    // must be mtpr
	    return csprintf("%-10s r%d,IPR(%#x)",
			    mnemonic, RA, ipr_index);
	}
	else {
	    // must be mfpr
	    return csprintf("%-10s IPR(%#x),r%d",
			    mnemonic, ipr_index, RA);
	}
    }
}};

def format HwMoveIPR(code) {{
    iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
			['IprAccessOp'])
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};


////////////////////////////////////////////////////////////////////
//
// Unimplemented instructions
//

output header {{
    /**
     * Static instruction class for unimplemented instructions that
     * cause simulator termination.  Note that these are recognized
     * (legal) instructions that the simulator does not support; the
     * 'Unknown' class is used for unrecognized/illegal instructions.
     * This is a leaf class.
     */
    class FailUnimplemented : public AlphaStaticInst
    {
      public:
	/// Constructor
	FailUnimplemented(const char *_mnemonic, MachInst _machInst)
	    : AlphaStaticInst(_mnemonic, _machInst, No_OpClass)
	{
	    // don't call execute() (which panics) if we're on a
	    // speculative path
	    flags[IsNonSpeculative] = true;
	}

	%(BasicExecDeclare)s

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };

    /**
     * Base class for unimplemented instructions that cause a warning
     * to be printed (but do not terminate simulation).  This
     * implementation is a little screwy in that it will print a
     * warning for each instance of a particular unimplemented machine
     * instruction, not just for each unimplemented opcode.  Should
     * probably make the 'warned' flag a static member of the derived
     * class.
     */
    class WarnUnimplemented : public AlphaStaticInst
    {
      private:
	/// Have we warned on this instruction yet?
	mutable bool warned;

      public:
	/// Constructor
	WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
	    : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
	{
	    // don't call execute() (which panics) if we're on a
	    // speculative path
	    flags[IsNonSpeculative] = true;
	}

	%(BasicExecDeclare)s

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

output decoder {{
    std::string
    FailUnimplemented::generateDisassembly(Addr pc,
					   const SymbolTable *symtab) const
    {
	return csprintf("%-10s (unimplemented)", mnemonic);
    }

    std::string
    WarnUnimplemented::generateDisassembly(Addr pc,
					   const SymbolTable *symtab) const
    {
#ifdef SS_COMPATIBLE_DISASSEMBLY
	return csprintf("%-10s", mnemonic);
#else
	return csprintf("%-10s (unimplemented)", mnemonic);
#endif
    }
}};

output exec {{
    Fault
    FailUnimplemented::execute(%(CPU_exec_context)s *xc,
			       Trace::InstRecord *traceData) const
    {
	panic("attempt to execute unimplemented instruction '%s' "
	      "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE);
	return Unimplemented_Opcode_Fault;
    }

    Fault
    WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
			       Trace::InstRecord *traceData) const
    {
	if (!warned) {
	    warn("instruction '%s' unimplemented\n", mnemonic);
	    warned = true;
	}

	return No_Fault;
    }
}};


def format FailUnimpl() {{
    iop = InstObjParams(name, 'FailUnimplemented')
    decode_block = BasicDecodeWithMnemonic.subst(iop)
}};

def format WarnUnimpl() {{
    iop = InstObjParams(name, 'WarnUnimplemented')
    decode_block = BasicDecodeWithMnemonic.subst(iop)
}};

output header {{
    /**
     * Static instruction class for unknown (illegal) instructions.
     * These cause simulator termination if they are executed in a
     * non-speculative mode.  This is a leaf class.
     */
    class Unknown : public AlphaStaticInst
    {
      public:
	/// Constructor
	Unknown(MachInst _machInst)
	    : AlphaStaticInst("unknown", _machInst, No_OpClass)
	{
	    // don't call execute() (which panics) if we're on a
	    // speculative path
	    flags[IsNonSpeculative] = true;
	}

	%(BasicExecDeclare)s

	std::string
	generateDisassembly(Addr pc, const SymbolTable *symtab) const;
    };
}};

////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//

output decoder {{
    std::string
    Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
	return csprintf("%-10s (inst 0x%x, opcode 0x%x)",
			"unknown", machInst, OPCODE);
    }
}};

output exec {{
    Fault
    Unknown::execute(%(CPU_exec_context)s *xc,
		     Trace::InstRecord *traceData) const
    {
	panic("attempt to execute unknown instruction "
	      "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
	return Unimplemented_Opcode_Fault;
    }
}};

def format Unknown() {{
    decode_block = 'return new Unknown(machInst);\n'
}};

////////////////////////////////////////////////////////////////////
//
// Utility functions for execute methods
//

output exec {{

    /// Return opa + opb, summing carry into third arg.
    inline uint64_t
    addc(uint64_t opa, uint64_t opb, int &carry)
    {
	uint64_t res = opa + opb;
	if (res < opa || res < opb)
	    ++carry;
	return res;
    }

    /// Multiply two 64-bit values (opa * opb), returning the 128-bit
    /// product in res_hi and res_lo.
    inline void
    mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo)
    {
	// do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies
	uint64_t opa_hi = opa<63:32>;
	uint64_t opa_lo = opa<31:0>;
	uint64_t opb_hi = opb<63:32>;
	uint64_t opb_lo = opb<31:0>;

	res_lo = opa_lo * opb_lo;

	// The middle partial products logically belong in bit
	// positions 95 to 32.  Thus the lower 32 bits of each product
	// sum into the upper 32 bits of the low result, while the
	// upper 32 sum into the low 32 bits of the upper result.
	uint64_t partial1 = opa_hi * opb_lo;
	uint64_t partial2 = opa_lo * opb_hi;

	uint64_t partial1_lo = partial1<31:0> << 32;
	uint64_t partial1_hi = partial1<63:32>;
	uint64_t partial2_lo = partial2<31:0> << 32;
	uint64_t partial2_hi = partial2<63:32>;

	// Add partial1_lo and partial2_lo to res_lo, keeping track
	// of any carries out
	int carry_out = 0;
	res_lo = addc(partial1_lo, res_lo, carry_out);
	res_lo = addc(partial2_lo, res_lo, carry_out);

	// Now calculate the high 64 bits...
	res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out;
    }

    /// Map 8-bit S-floating exponent to 11-bit T-floating exponent.
    /// See Table 2-2 of Alpha AHB.
    inline int
    map_s(int old_exp)
    {
	int hibit = old_exp<7:>;
	int lobits = old_exp<6:0>;

	if (hibit == 1) {
	    return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits);
	}
	else {
	    return (lobits == 0) ? 0 : (0x380 | lobits);
	}
    }

    /// Convert a 32-bit S-floating value to the equivalent 64-bit
    /// representation to be stored in an FP reg.
    inline uint64_t
    s_to_t(uint32_t s_val)
    {
	uint64_t tmp = s_val;
	return (tmp<31:> << 63 // sign bit
		| (uint64_t)map_s(tmp<30:23>) << 52 // exponent
		| tmp<22:0> << 29); // fraction
    }

    /// Convert a 64-bit T-floating value to the equivalent 32-bit
    /// S-floating representation to be stored in memory.
    inline int32_t
    t_to_s(uint64_t t_val)
    {
	return (t_val<63:62> << 30   // sign bit & hi exp bit
		| t_val<58:29>);     // rest of exp & fraction
    }
}};

////////////////////////////////////////////////////////////////////
//
// The actual decoder specification
//

decode OPCODE default Unknown::unknown() {

    format LoadAddress {
	0x08: lda({{ Ra = Rb + disp; }});
	0x09: ldah({{ Ra = Rb + (disp << 16); }});
    }

    format LoadOrNop {
	0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }});
	0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }});
	0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }});
	0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }});
	0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
	0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED);
	0x20: copy_load({{EA = Ra;}}, 
	                {{fault = xc->copySrcTranslate(EA);}},
			IsMemRef, IsLoad, IsCopy);
    }

    format LoadOrPrefetch {
	0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }});
	0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT);
	// IsFloating flag on lds gets the prefetch to disassemble
	// using f31 instead of r31... funcitonally it's unnecessary
	0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }},
		  PF_EXCLUSIVE, IsFloating);  
    }

    format Store {
	0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }});
	0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }});
	0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }});
	0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }});
	0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }});
	0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
	0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
	0x24: copy_store({{EA = Rb;}},
	                 {{fault = xc->copy(EA);}},
			 IsMemRef, IsStore, IsCopy);
    }

    format StoreCond {
	0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }},
		    {{
			uint64_t tmp = Mem_write_result;
			// see stq_c
			Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
		    }}, LOCKED);
	0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }},
		    {{
			uint64_t tmp = Mem_write_result;
			// If the write operation returns 0 or 1, then
			// this was a conventional store conditional,
			// and the value indicates the success/failure
			// of the operation.  If another value is
			// returned, then this was a Turbolaser
			// mailbox access, and we don't update the
			// result register at all.
			Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
		    }}, LOCKED);
    }

    format IntegerOperate {

	0x10: decode INTFUNC {	// integer arithmetic operations

	    0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }});
	    0x40: addlv({{
		uint32_t tmp  = Ra.sl + Rb_or_imm.sl;
		// signed overflow occurs when operands have same sign
		// and sign of result does not match.
		if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>)
		    fault = Integer_Overflow_Fault;
		Rc.sl = tmp;
	    }});
	    0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }});
	    0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }});

	    0x20: addq({{ Rc = Ra + Rb_or_imm; }});
	    0x60: addqv({{
		uint64_t tmp = Ra + Rb_or_imm;
		// signed overflow occurs when operands have same sign
		// and sign of result does not match.
		if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>)
		    fault = Integer_Overflow_Fault;
		Rc = tmp;
	    }});
	    0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }});
	    0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }});

	    0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }});
	    0x49: sublv({{
		uint32_t tmp  = Ra.sl - Rb_or_imm.sl;
		// signed overflow detection is same as for add,
		// except we need to look at the *complemented*
		// sign bit of the subtrahend (Rb), i.e., if the initial
		// signs are the *same* then no overflow can occur
		if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>)
		    fault = Integer_Overflow_Fault;
		Rc.sl = tmp;
	    }});
	    0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }});
	    0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }});

	    0x29: subq({{ Rc = Ra - Rb_or_imm; }});
	    0x69: subqv({{
		uint64_t tmp  = Ra - Rb_or_imm;
		// signed overflow detection is same as for add,
		// except we need to look at the *complemented*
		// sign bit of the subtrahend (Rb), i.e., if the initial
		// signs are the *same* then no overflow can occur
		if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>)
		    fault = Integer_Overflow_Fault;
		Rc = tmp;
	    }});
	    0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }});
	    0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }});

	    0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }});
	    0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }});
	    0x4d: cmplt({{ Rc = (Ra.sq <  Rb_or_imm.sq); }});
	    0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }});
	    0x1d: cmpult({{ Rc = (Ra.uq <  Rb_or_imm.uq); }});

	    0x0f: cmpbge({{
		int hi = 7;
		int lo = 0;
		uint64_t tmp = 0;
		for (int i = 0; i < 8; ++i) {
		    tmp |= (Ra.uq<hi:lo> >= Rb_or_imm.uq<hi:lo>) << i;
		    hi += 8;
		    lo += 8;
		}
		Rc = tmp;
	    }});
	}

	0x11: decode INTFUNC {	// integer logical operations

	    0x00: and({{ Rc = Ra & Rb_or_imm; }});
	    0x08: bic({{ Rc = Ra & ~Rb_or_imm; }});
	    0x20: bis({{ Rc = Ra | Rb_or_imm; }});
	    0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }});
	    0x40: xor({{ Rc = Ra ^ Rb_or_imm; }});
	    0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }});

	    // conditional moves
	    0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }});
	    0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }});
	    0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }});
	    0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }});
	    0x44: cmovlt({{ Rc = (Ra.sq <  0) ? Rb_or_imm : Rc; }});
	    0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }});
	    0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }});
	    0x66: cmovgt({{ Rc = (Ra.sq >  0) ? Rb_or_imm : Rc; }});

	    // For AMASK, RA must be R31.
	    0x61: decode RA {
		31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }});
	    }

	    // For IMPLVER, RA must be R31 and the B operand
	    // must be the immediate value 1.
	    0x6c: decode RA {
		31: decode IMM {
		    1: decode INTIMM {
			// return EV5 for FULL_SYSTEM and EV6 otherwise
			1: implver({{
#ifdef FULL_SYSTEM
			     Rc = 1;
#else
			     Rc = 2;
#endif
			}});
		    }
		}
	    }

#ifdef FULL_SYSTEM
	    // The mysterious 11.25...
	    0x25: WarnUnimpl::eleven25();
#endif
	}

	0x12: decode INTFUNC {
	    0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }});
	    0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }});
	    0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }});

	    0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }});
	    0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }});
	    0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }});
	    0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }});

	    0x52: mskwh({{
		int bv = Rb_or_imm<2:0>;
		Rc =  bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra;
	    }});
	    0x62: msklh({{
		int bv = Rb_or_imm<2:0>;
		Rc =  bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra;
	    }});
	    0x72: mskqh({{
		int bv = Rb_or_imm<2:0>;
		Rc =  bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra;
	    }});

	    0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }});
	    0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }});
	    0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }});
	    0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }});

	    0x5a: extwh({{
		Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }});
	    0x6a: extlh({{
		Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }});
	    0x7a: extqh({{
		Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }});

	    0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }});
	    0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }});
	    0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }});
	    0x3b: insql({{ Rc = Ra       << (Rb_or_imm<2:0> * 8); }});

	    0x57: inswh({{
		int bv = Rb_or_imm<2:0>;
		Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0;
	    }});
	    0x67: inslh({{
		int bv = Rb_or_imm<2:0>;
		Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0;
	    }});
	    0x77: insqh({{
		int bv = Rb_or_imm<2:0>;
		Rc = bv ? (Ra.uq       >> (64 - 8 * bv)) : 0;
	    }});

	    0x30: zap({{
		uint64_t zapmask = 0;
		for (int i = 0; i < 8; ++i) {
		    if (Rb_or_imm<i:>)
			zapmask |= (mask(8) << (i * 8));
		}
		Rc = Ra & ~zapmask;
	    }});
	    0x31: zapnot({{
		uint64_t zapmask = 0;
		for (int i = 0; i < 8; ++i) {
		    if (!Rb_or_imm<i:>)
			zapmask |= (mask(8) << (i * 8));
		}
		Rc = Ra & ~zapmask;
	    }});
	}

	0x13: decode INTFUNC {	// integer multiplies
	    0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp);
	    0x20: mulq({{ Rc    = Ra    * Rb_or_imm;    }}, IntMultOp);
	    0x30: umulh({{
		uint64_t hi, lo;
		mul128(Ra, Rb_or_imm, hi, lo);
		Rc = hi;
	    }}, IntMultOp);
	    0x40: mullv({{
		// 32-bit multiply with trap on overflow
		int64_t Rax = Ra.sl;	// sign extended version of Ra.sl
		int64_t Rbx = Rb_or_imm.sl;
		int64_t tmp = Rax * Rbx;
		// To avoid overflow, all the upper 32 bits must match
		// the sign bit of the lower 32.  We code this as
		// checking the upper 33 bits for all 0s or all 1s.
		uint64_t sign_bits = tmp<63:31>;
		if (sign_bits != 0 && sign_bits != mask(33))
		    fault = Integer_Overflow_Fault;
		Rc.sl = tmp<31:0>;
	    }}, IntMultOp);
	    0x60: mulqv({{
		// 64-bit multiply with trap on overflow
		uint64_t hi, lo;
		mul128(Ra, Rb_or_imm, hi, lo);
		// all the upper 64 bits must match the sign bit of
		// the lower 64
		if (!((hi == 0 && lo<63:> == 0) ||
		      (hi == mask(64) && lo<63:> == 1)))
		    fault = Integer_Overflow_Fault;
		Rc = lo;
	    }}, IntMultOp);
	}

	0x1c: decode INTFUNC {
	    0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); }
	    0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); }
        0x32: ctlz({{
            uint64_t count = 0;
            uint64_t temp = Rb;
            if (temp<63:32>) temp >>= 32; else count += 32;
            if (temp<31:16>) temp >>= 16; else count += 16;
            if (temp<15:8>) temp >>= 8; else count += 8;
            if (temp<7:4>) temp >>= 4; else count += 4;
            if (temp<3:2>) temp >>= 2; else count += 2;
            if (temp<1:1>) temp >>= 1; else count += 1;
            if ((temp<0:0>) != 0x1) count += 1; 
            Rc = count; 
            }}, IntAluOp);
         
        0x33: cttz({{
            uint64_t count = 0;
            uint64_t temp = Rb;
            if (!(temp<31:0>)) { temp >>= 32; count += 32; }
            if (!(temp<15:0>)) { temp >>= 16; count += 16; }
            if (!(temp<7:0>)) { temp >>= 8; count += 8; }
            if (!(temp<3:0>)) { temp >>= 4; count += 4; }
            if (!(temp<1:0>)) { temp >>= 2; count += 2; }
            if (!(temp<0:0> & ULL(0x1))) count += 1; 
            Rc = count; 
        }}, IntAluOp);

	    format FailUnimpl {
		0x30: ctpop();
		0x31: perr();
		0x34: unpkbw();
		0x35: unpkbl();
		0x36: pkwb();
		0x37: pklb();
		0x38: minsb8();
		0x39: minsw4();
		0x3a: minub8();
		0x3b: minuw4();
		0x3c: maxub8();
		0x3d: maxuw4();
		0x3e: maxsb8();
		0x3f: maxsw4();
	    }

	    format BasicOperateWithNopCheck {
		0x70: decode RB {
		    31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp);
		}
		0x78: decode RB {
		    31: ftois({{ Rc.sl = t_to_s(Fa.uq); }},
			      FloatCvtOp);
		}
	    }
	}
    }

    // Conditional branches.
    format CondBranch {
	0x39: beq({{ cond = (Ra == 0); }});
	0x3d: bne({{ cond = (Ra != 0); }});
	0x3e: bge({{ cond = (Ra.sq >= 0); }});
	0x3f: bgt({{ cond = (Ra.sq >  0); }});
	0x3b: ble({{ cond = (Ra.sq <= 0); }});
	0x3a: blt({{ cond = (Ra.sq < 0); }});
	0x38: blbc({{ cond = ((Ra & 1) == 0); }});
	0x3c: blbs({{ cond = ((Ra & 1) == 1); }});

	0x31: fbeq({{ cond = (Fa == 0); }});
	0x35: fbne({{ cond = (Fa != 0); }});
	0x36: fbge({{ cond = (Fa >= 0); }});
	0x37: fbgt({{ cond = (Fa >  0); }});
	0x33: fble({{ cond = (Fa <= 0); }});
	0x32: fblt({{ cond = (Fa < 0); }});
    }

    // unconditional branches
    format UncondBranch {
	0x30: br();
	0x34: bsr(IsCall);
    }

    // indirect branches
    0x1a: decode JMPFUNC {
	format Jump {
	    0: jmp();
	    1: jsr(IsCall);
	    2: ret(IsReturn);
	    3: jsr_coroutine(IsCall, IsReturn);
	}
    }

    // IEEE floating point
    0x14: decode FP_SHORTFUNC {
	// Integer to FP register moves must have RB == 31
	0x4: decode RB {
	    31: decode FP_FULLFUNC {
		format BasicOperateWithNopCheck {
		    0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp);
		    0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp);
		    0x014: FailUnimpl::itoff();	// VAX-format conversion
		}
	    }
	}

	// Square root instructions must have FA == 31
	0xb: decode FA {
	    31: decode FP_TYPEFUNC {
		format FloatingPointOperate {
#ifdef SS_COMPATIBLE_FP
		    0x0b: sqrts({{
			if (Fb < 0.0)
			    fault = Arithmetic_Fault;
			Fc = sqrt(Fb);
		    }}, FloatSqrtOp);
#else
		    0x0b: sqrts({{
			if (Fb.sf < 0.0)
			    fault = Arithmetic_Fault;
			Fc.sf = sqrt(Fb.sf);
		    }}, FloatSqrtOp);
#endif
		    0x2b: sqrtt({{
			if (Fb < 0.0)
			    fault = Arithmetic_Fault;
			Fc = sqrt(Fb);
		    }}, FloatSqrtOp);
		}
	    }
	}

	// VAX-format sqrtf and sqrtg are not implemented
	0xa: FailUnimpl::sqrtfg();
    }

    // IEEE floating point
    0x16: decode FP_SHORTFUNC_TOP2 {
	// The top two bits of the short function code break this space
	// into four groups: binary ops, compares, reserved, and conversions.
	// See Table 4-12 of AHB.	
	// Most of these instructions may have various trapping and
	// rounding mode flags set; these are decoded in the
	// FloatingPointDecode template used by the
	// FloatingPointOperate format.

	// add/sub/mul/div: just decode on the short function code
	// and source type.
	0: decode FP_TYPEFUNC {
	    format FloatingPointOperate {
#ifdef SS_COMPATIBLE_FP
		0x00: adds({{ Fc = Fa + Fb; }});
		0x01: subs({{ Fc = Fa - Fb; }});
		0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp);
		0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp);
#else
		0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }});
		0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }});
		0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp);
		0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp);
#endif

		0x20: addt({{ Fc = Fa + Fb; }});
		0x21: subt({{ Fc = Fa - Fb; }});
		0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp);
		0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp);
	    }
	}

	// Floating-point compare instructions must have the default
	// rounding mode, and may use the default trapping mode or
	// /SU.  Both trapping modes are treated the same by M5; the
	// only difference on the real hardware (as far a I can tell)
	// is that without /SU you'd get an imprecise trap if you
	// tried to compare a NaN with something else (instead of an
	// "unordered" result).
	1: decode FP_FULLFUNC {
	    format BasicOperateWithNopCheck {
		0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }},
				     FloatCmpOp);
		0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }},
				     FloatCmpOp);
		0x0a6, 0x5a6: cmptlt({{ Fc = (Fa <  Fb) ? 2.0 : 0.0; }},
				     FloatCmpOp);
		0x0a4, 0x5a4: cmptun({{ // unordered
		    Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0;
		}}, FloatCmpOp);
	    }
	}

	// The FP-to-integer and integer-to-FP conversion insts
	// require that FA be 31.
	3: decode FA {
	    31: decode FP_TYPEFUNC {
		format FloatingPointOperate {
		    0x2f: cvttq({{ Fc.sq = (int64_t)rint(Fb); }});

		    // The cvtts opcode is overloaded to be cvtst if the trap
		    // mode is 2 or 6 (which are not valid otherwise)
		    0x2c: decode FP_FULLFUNC {
			format BasicOperateWithNopCheck {
			    // trap on denorm version "cvtst/s" is
			    // simulated same as cvtst
			    0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }});
			}
		      default: cvtts({{ Fc.sf = Fb; }});
		    }

		    // The trapping mode for integer-to-FP conversions
		    // must be /SUI or nothing; /U and /SU are not
		    // allowed.  The full set of rounding modes are
		    // supported though.
		    0x3c: decode FP_TRAPMODE {
			0,7: cvtqs({{ Fc.sf = Fb.sq; }});
		    }
		    0x3e: decode FP_TRAPMODE {
			0,7: cvtqt({{ Fc    = Fb.sq; }});
		    }
		}
	    }
	}
    }

    // misc FP operate
    0x17: decode FP_FULLFUNC {
	format BasicOperateWithNopCheck {
	    0x010: cvtlq({{
		Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>;
	    }});
	    0x030: cvtql({{
		Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29);
	    }});

	    // We treat the precise & imprecise trapping versions of
	    // cvtql identically.
	    0x130, 0x530: cvtqlv({{
		// To avoid overflow, all the upper 32 bits must match
		// the sign bit of the lower 32.  We code this as
		// checking the upper 33 bits for all 0s or all 1s.
		uint64_t sign_bits = Fb.uq<63:31>;
		if (sign_bits != 0 && sign_bits != mask(33))
		    fault = Integer_Overflow_Fault;
		Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29);
	    }});

	    0x020: cpys({{  // copy sign
		Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>;
	    }});
	    0x021: cpysn({{ // copy sign negated
		Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>;
	    }});
	    0x022: cpyse({{ // copy sign and exponent
		Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>;
	    }});

	    0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }});
	    0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }});
	    0x02c: fcmovlt({{ Fc = (Fa <  0) ? Fb : Fc; }});
	    0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }});
	    0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }});
	    0x02f: fcmovgt({{ Fc = (Fa >  0) ? Fb : Fc; }});

	    0x024: mt_fpcr({{ FPCR = Fa.uq; }});
	    0x025: mf_fpcr({{ Fa.uq = FPCR; }});
	}
    }

    // miscellaneous mem-format ops
    0x18: decode MEMFUNC {
	format WarnUnimpl {
	    0x8000: fetch();
	    0xa000: fetch_m();
	    0xe800: ecb();
	}

	format MiscPrefetch {
	    0xf800: wh64({{ EA = Rb & ~ULL(63); }},
			 {{ xc->writeHint(EA, 64, memAccessFlags); }},
			 IsMemRef, IsDataPrefetch, IsStore, MemWriteOp,
			 NO_FAULT);
	}

	format BasicOperate {
	    0xc000: rpcc({{
#ifdef FULL_SYSTEM
        /* Rb is a fake dependency so here is a fun way to get
         * the parser to understand that.
         */
		Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0);
        
#else
		Ra = curTick;
#endif
	    }});

	    // All of the barrier instructions below do nothing in
	    // their execute() methods (hence the empty code blocks).
	    // All of their functionality is hard-coded in the
	    // pipeline based on the flags IsSerializing,
	    // IsMemBarrier, and IsWriteBarrier.  In the current
	    // detailed CPU model, the execute() function only gets
	    // called at fetch, so there's no way to generate pipeline
	    // behavior at any other stage.  Once we go to an
	    // exec-in-exec CPU model we should be able to get rid of
	    // these flags and implement this behavior via the
	    // execute() methods.

	    // trapb is just a barrier on integer traps, where excb is
	    // a barrier on integer and FP traps.  "EXCB is thus a
	    // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
	    // them the same though.
	    0x0000: trapb({{ }}, IsSerializing, No_OpClass);
	    0x0400: excb({{ }}, IsSerializing, No_OpClass);
	    0x4000: mb({{ }}, IsMemBarrier, MemReadOp);
	    0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp);
	}

#ifdef FULL_SYSTEM
	format BasicOperate {
	    0xe000: rc({{
		Ra = xc->readIntrFlag();
		xc->setIntrFlag(0);
	    }}, IsNonSpeculative);
	    0xf000: rs({{
		Ra = xc->readIntrFlag();
		xc->setIntrFlag(1);
	    }}, IsNonSpeculative);
	}
#else
	format FailUnimpl {
	    0xe000: rc();
	    0xf000: rs();
	}
#endif
    }

#ifdef FULL_SYSTEM
    0x00: CallPal::call_pal({{
	if (!palValid ||
	    (palPriv
	     && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) {
	    // invalid pal function code, or attempt to do privileged
	    // PAL call in non-kernel mode
	    fault = Unimplemented_Opcode_Fault;
	}
	else {
	    // check to see if simulator wants to do something special
	    // on this PAL call (including maybe suppress it)
	    bool dopal = xc->simPalCheck(palFunc);

	    if (dopal) {
		AlphaISA::swap_palshadow(&xc->xcBase()->regs, true);
		xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC);
		NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset;
	    }
	}
    }}, IsNonSpeculative);
#else
    0x00: decode PALFUNC {
	format EmulatedCallPal {
	    0x00: halt ({{
		SimExit(curTick, "halt instruction encountered");
	    }}, IsNonSpeculative);
	    0x83: callsys({{ 
		xc->syscall();
	    }}, IsNonSpeculative);
	    // Read uniq reg into ABI return value register (r0)
	    0x9e: rduniq({{ R0 = Runiq; }});
	    // Write uniq reg with value from ABI arg register (r16)
	    0x9f: wruniq({{ Runiq = R16; }});
	}
    }
#endif

#ifdef FULL_SYSTEM
    format HwLoadStore {
	0x1b: decode HW_LDST_QUAD {
	    0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L);
	    1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q);
	}

	0x1f: decode HW_LDST_COND {
	    0: decode HW_LDST_QUAD {
		0: hw_st({{ EA = (Rb + disp) & ~3; }},
			 {{ Mem.ul = Ra<31:0>; }}, L);
		1: hw_st({{ EA = (Rb + disp) & ~7; }},
			 {{ Mem.uq = Ra.uq; }}, Q);
	    }

	    1: FailUnimpl::hw_st_cond();
	}
    }

    format BasicOperate {
	0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing);

	// M5 special opcodes use the reserved 0x01 opcode space
	0x01: decode M5FUNC {
	    0x00: arm({{
		AlphaPseudo::arm(xc->xcBase());
	    }}, IsNonSpeculative);
	    0x01: quiesce({{
		AlphaPseudo::quiesce(xc->xcBase());
	    }}, IsNonSpeculative);
	    0x10: ivlb({{
		AlphaPseudo::ivlb(xc->xcBase());
	    }}, No_OpClass, IsNonSpeculative);
	    0x11: ivle({{
		AlphaPseudo::ivle(xc->xcBase());
	    }}, No_OpClass, IsNonSpeculative);
	    0x20: m5exit_old({{
		AlphaPseudo::m5exit_old(xc->xcBase());
	    }}, No_OpClass, IsNonSpeculative);
	    0x21: m5exit({{
		AlphaPseudo::m5exit(xc->xcBase());
	    }}, No_OpClass, IsNonSpeculative);
            0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }});
            0x40: resetstats({{
		AlphaPseudo::resetstats(xc->xcBase());
	    }}, IsNonSpeculative);
            0x41: dumpstats({{
		AlphaPseudo::dumpstats(xc->xcBase());
	    }}, IsNonSpeculative);
            0x42: dumpresetstats({{
		AlphaPseudo::dumpresetstats(xc->xcBase());
	    }}, IsNonSpeculative);
            0x43: m5checkpoint({{
		AlphaPseudo::m5checkpoint(xc->xcBase());
	    }}, IsNonSpeculative);
            0x50: m5readfile({{
		AlphaPseudo::readfile(xc->xcBase());
	    }}, IsNonSpeculative);
            0x51: m5break({{
        AlphaPseudo::debugbreak(xc->xcBase());
        }}, IsNonSpeculative);
            0x52: m5switchcpu({{
        AlphaPseudo::switchcpu(xc->xcBase());
        }}, IsNonSpeculative);

	}
    }

    format HwMoveIPR {
	0x19: hw_mfpr({{
	    // this instruction is only valid in PAL mode
	    if (!xc->inPalMode()) {
		fault = Unimplemented_Opcode_Fault;
	    }
	    else {
		Ra = xc->readIpr(ipr_index, fault);
	    }
	}});
	0x1d: hw_mtpr({{
	    // this instruction is only valid in PAL mode
	    if (!xc->inPalMode()) {
		fault = Unimplemented_Opcode_Fault;
	    }
	    else {
		xc->setIpr(ipr_index, Ra);
		if (traceData) { traceData->setData(Ra); }
	    }
	}});
    }
#endif
}
