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

// 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"
