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

// Copyright (c) 2003-2005 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt

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


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

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

#include "arch/alpha/faults.hh"
#include "arch/alpha/types.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
#include "mem/request.hh"  // some constructors use MemReq flags
}};

output decoder {{
#include <cmath>

#include "arch/alpha/decoder.hh"
#include "arch/alpha/registers.hh"
#include "arch/alpha/regredir.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/thread_context.hh"  // for Jump::branchTarget()
#include "mem/packet.hh"
#include "sim/full_system.hh"

using namespace AlphaISA;
}};

output exec {{
#include <cmath>

#include "arch/alpha/decoder.hh"
#include "arch/alpha/registers.hh"
#include "arch/alpha/regredir.hh"
#include "arch/generic/memhelpers.hh"
#include "base/cp_annotate.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/full_system.hh"
#include "sim/pseudo_inst.hh"
#include "sim/sim_exit.hh"

using namespace AlphaISA;
}};

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


namespace AlphaISA;

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

// Universal (format-independent) fields
def bitfield PALMODE    <32:32>;
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' : 'int8_t',
    'ub' : 'uint8_t',
    'sw' : 'int16_t',
    'uw' : 'uint16_t',
    'sl' : 'int32_t',
    'ul' : 'uint32_t',
    'sq' : 'int64_t',
    'uq' : 'uint64_t',
    'sf' : 'float',
    'df' : 'double'
}};

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': ('IntReg', 'uq', 'PALMODE ? reg_redir[RA] : RA',
           'IsInteger', 1),
    'Rb': ('IntReg', 'uq', 'PALMODE ? reg_redir[RB] : RB',
           'IsInteger', 2),
    'Rc': ('IntReg', 'uq', 'PALMODE ? reg_redir[RC] : RC',
           'IsInteger', 3),
    'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
    'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
    'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
    'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
    'PC': ('PCState', 'uq', 'pc', ( None, None, 'IsControl' ), 4),
    'NPC': ('PCState', 'uq', 'npc', ( None, None, 'IsControl' ), 4),
    'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1),
    'FPCR':  ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1),
    'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1),
    # The next two are hacks for non-full-system call-pal emulation
    'R0':  ('IntReg', 'uq', '0', None, 1),
    'R16': ('IntReg', 'uq', '16', None, 1),
    'R17': ('IntReg', 'uq', '17', None, 1),
    'R18': ('IntReg', 'uq', '18', 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
    {
      protected:

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

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

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

        void
        advancePC(AlphaISA::PCState &pcState) const
        {
            pcState.advance();
        }
    };
}};

output decoder {{
    void
    AlphaStaticInst::printReg(std::ostream &os, RegId reg) const
    {
        if (reg.isIntReg()) {
            ccprintf(os, "r%d", reg.index());
        }
        else {
            ccprintf(os, "f%d", reg.index());
        }
    }

    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();
    }
}};

// 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(ExtMachInst machInst);

        Fault execute(ExecContext *, Trace::InstRecord *) const;
    };
}};

// Basic instruction class constructor template.
def template BasicConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst 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(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

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

        if (fault == NoFault) {
            %(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', 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, ExtMachInst _machInst)
            : AlphaStaticInst("nop", _machInst, No_OpClass),
              originalDisassembly(_originalDisassembly)
        {
            flags[IsNop] = true;
        }

        ~Nop() { }

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

        Fault execute(ExecContext *, Trace::InstRecord *) const;
    };

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

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
    }
}};

output exec {{
    Fault
    Nop::execute(ExecContext *, Trace::InstRecord *) const
    {
        return NoFault;
    }
}};

// 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', code, opt_args)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = OperateNopCheckDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

// Integer instruction templates, formats, etc.
##include "int.isa"

// Floating-point instruction templates, formats, etc.
##include "fp.isa"

// Memory instruction templates, formats, etc.
##include "mem.isa"

// Branch/jump instruction templates, formats, etc.
##include "branch.isa"

// PAL instruction templates, formats, etc.
##include "pal.isa"

// Opcdec fault instruction templates, formats, etc.
##include "opcdec.isa"

// Unimplemented instruction templates, formats, etc.
##include "unimp.isa"

// Unknown instruction templates, formats, etc.
##include "unknown.isa"

// Execution utility functions
##include "util.isa"

// The actual decoder
##include "decoder.isa"
