// -*- 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:

        /// 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_Reg_Base = AlphaISA::FP_Reg_Base
        };

        /// 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, int 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, int reg) const
    {
        if (reg < FP_Reg_Base) {
            ccprintf(os, "r%d", reg);
        }
        else {
            ccprintf(os, "f%d", reg - FP_Reg_Base);
        }
    }

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

        %(BasicExecDeclare)s
    };
}};

// 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(CPU_EXEC_CONTEXT *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;

        %(BasicExecDeclare)s
    };

    /// 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(CPU_EXEC_CONTEXT *, 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"
